Принудительно выполнить вызов действия с одним контроллером Rails Из примера RSpec

#ruby-on-rails #unit-testing #rspec #cancan

#ruby-на-рельсах #модульное тестирование #рспек #канкан #ruby-on-rails #rspec #cancan

Вопрос:

Пожалуйста, потерпите меня, пока я расскажу о своем вопросе:

Недавно я интегрировал CanCan в наше приложение и обнаружил, что один из тестов контроллера rspec не удался. Оказывается, это было результатом того, что тест был плохо написан и дважды вызывал действие на контроллере.

   it 'only assigns users for the organisation as @users' do
    xhr :get, :users, { id: first_organisation.to_param}
    expect(assigns(:users).count).to eq(3)

    xhr :get, :users, { id: second_organisation.to_param}
    expect(assigns(:users).count).to eq(4)
  end
  

Обратите внимание, что пример сокращен для краткости.

Теперь причина сбоя заключается в том, что rspec использует один и тот же экземпляр контроллера для обоих вызовов действий, а CanCan загружает ресурс организации только в том случае, если он еще не загружен.

Я могу согласиться с аргументацией, лежащей в основе а) rspec, использующего один экземпляр контроллера для области примера, и б) для CanCan, который загружает ресурс только в том случае, если он не существует.

Реальная проблема здесь заключается в том, что, конечно, это плохая идея — вызывать действие дважды в одном и том же примере. Теперь введение CanCan высветило ошибку в этом примере, но теперь я обеспокоен тем, что могут быть другие тесты контроллера, которые также вызывают действия дважды, или что такие примеры могут быть написаны в будущем, что, довольно многословно, приводит меня к моему вопросу:

Возможно ли обеспечить, чтобы пример controller rspec мог вызывать только одно действие контроллера?

Ответ №1:

Хорошо, похоже, у меня есть решение:

Создайте unity_helper.rb, чтобы перейти к спецификации / поддержке

 module UnityExtension
  class UnityException < StandardError
  end

  def check_unity
    if @unity
      raise UnityException, message: 'Example is not a unit test!'
    end

    @unity = true
  end
end

RSpec.configure do |config|
  config.before(:all, type: :controller)  do
    ApplicationController.prepend UnityExtension
    ApplicationController.prepend_before_action :check_unity
  end
end
  

затем в rails_helper.rb

 require 'support/unity_helper'
  

И это фактически выделило другой пример контроллера rspec, который вызывает контроллер дважды.

Я открыт для других решений или улучшений моего.