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

时间:2019-02-14 16:22:32

标签: ruby-on-rails ruby rspec

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

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

current_user由zendesk_api gem提供,我们将其用于身份验证。具体来说,current_userclient.rbzendesk_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使用,或规范中的第三方呼叫,我是否应该遵循任何最佳做法?

1 个答案:

答案 0 :(得分:1)

在此处测试控制器并使用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