#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, который вызывает контроллер дважды.
Я открыт для других решений или улучшений моего.