关于在编写规范时使用 instance_eval 存根的最佳实践?

Best practices regarding using instance_eval to stub while writing specs?

我有很多看起来像这样的代码,但我在为其编写测试时遇到了问题:

class MyController < ApplicationController
  def my_endpoint
    id = current_user.site_id
    do_something_with id
  end
end

current_user 由我们用于身份验证的 zendesk_api gem 提供。具体来说,current_userclient.rb 上的一种方法:zendesk_api-1.14.4/lib/zendesk_api/client.rb#current_user.

我发现我可以通过在我的规范中使用 instance_eval 存根 MyController#current_user:

describe "#my_endpoint" do
it "should etc" do
  controller = MyController.new
  controller.instance_eval do
    def current_user
      return OpenStruct.new(:site_id => 1)
    end
  end

  response = controller.my_endpoint
end

我觉得这个规范代码看起来不错。它具有可读性和灵活性。但是,我找不到关于 instance_eval.

用法的最佳实践

这是instance_eval的常规用法吗?有没有我应该改用的约定?关于 instance_eval 在规范中的使用,或者以其他方式在规范中存根第 3 方调用,是否有任何我应该遵循的最佳实践?

当您在这里测试控制器并使用 rspec 时,您应该 define the tests as one such:

describe MyController, type: :controller do
  ...(tests here)
end

在这样的控制器测试中,您可以通过 controller 方法访问控制器实例,并且可以使用 rspec's mocking capabilities

存根调用 current_user
describe MyController, type: :controller do
  before do
    allow(controller)
      .to_receive(:current_user)
      .and_return(OpenStruct.new(:site_id => 1))
  end

  it 'is testing something' do
    ...
  end
end