RSpec 3.5将参数传递给shared_context

时间:2016-08-05 16:02:24

标签: ruby-on-rails rspec rspec-rails ruby-on-rails-5 rspec3

我有这个代码,我想在几个规范中重用:

RSpec.shared_context "a UserWorker" do |user|

  let(:mock_context_user) {{
    id: 1,
    brand: user.brand,
    backend_token: user.backend_token
  }}

  before(:each) do
    allow(SomeClass).to receive(:some_method)
      .with(user.id).and_return(mock_context_user)
  end

  before(:each, context: true) do
    Sidekiq::Testing.inline!
  end

  after(:each, context: true) do
    Sidekiq::Testing.fake!
  end

end

在使用共享代码的spec文件中:

let(:user) { build :user } # FactoryGirl

...

describe '#perform' do
  # some lets here

  include_context 'a UserWorker', user

  context 'when something exists' do
    it 'does some stuff' do
      # test some stuff here
    end
  end
end

但是这给了我这个错误:

/.rvm/gems/ruby-2.3.0@fb-cont/gems/rspec-core-3.5.1/lib/rspec/core/example_group.rb:724:in `method_missing': `user` is not available on an example group (e.g. a `describe` or `context` block). It is only available from within individual examples (e.g. `it` blocks) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). (RSpec::Core::ExampleGroup::WrongScopeError)

连连呢?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

RSpec docs并不是很明确,但是您可以通过将包含let()调用的块传递给include_context来注入其他值。规范传递的“定制块”将首先进行评估,并且可用于共享上下文中声明的代码。

这是一个共享的上下文,取决于包含它的规范以let()的值value_from_spec,然后设置更多的值,一个通过let(),一个通过{{ 1}}区块:

before()

(请注意,与OP的RSpec.shared_context('a context', shared_context: :metadata) do # assume the existence of value_from_spec let(:a_value_from_context) { value_from_spec - 1 } before(:each) do # assume the existence of value_from_spec @another_value_from_context = value_from_spec + 1 end end 示例不同,我们从不显式声明|user|,我们只是相信可以在需要时使用它。如果您想使发生的事情更加明显,则可以检查value_from_spec并引发错误。)

这是一个注入该值并读取共享上下文对其的转换的规范:

defined?(:value_from_spec)

答案 1 :(得分:1)

由于它始终会返回相同的mock_context_user,因此您可以尝试更通用的内容,例如:

allow(SomeClass)
 .to receive(:some_method)
 .with(an_instance_of(Fixnum))
 .and_return(mock_context_user)

但我不确定an_instance_of是否适用于RSpec 3.5,它是RSpec 3.3。