从 RSpec 示例强制执行单个 Rails 控制器操作调用

Enforce Single Rails Controller Action Invocation From An RSpec Example

请耐心等待我为我的问题提供一些背景知识:

我最近将 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 仅在组织资源尚未加载时才加载它。

我可以接受 a) rspec 在示例范围内使用控制器的单个实例和 b) CanCan 仅在资源不存在时才加载资源的原因。

这里真正的问题是,在同一个示例中两次调用一个动作当然不是一个好主意。现在 CanCan 的介绍突出了这个例子中的错误,但我现在担心可能还有其他控制器测试也会调用两次动作,或者将来可能会编写这样的例子,这相当冗长,导致我我的问题:

是否可以强制控制器 rspec 示例只能调用单个控制器操作?

好的,看来我有解决办法:

创建unity_helper.rb进入spec/support

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 控制器示例,该示例调用控制器两次。

我愿意接受其他解决方案或对我的改进。