ruby on rails-RSpec 3.5将参数传递给shared_context



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

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

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

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)

建议?感谢您的帮助。

RSpec文档对此并不十分清楚,但您可以通过将包含let()调用的块传递给include_context来注入额外的值。规范传递的"自定义块"将首先进行评估,并且可用于在共享上下文中声明的代码。

这里有一个共享上下文,它取决于规范,包括它到let()的值value_from_spec,然后再设置几个值,一个通过let(),一个经由before()块:

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

(注意,与OP的|user|示例不同,我们从未明确声明value_from_spec,我们只是相信它会在我们需要的时候出现。如果你想让事情变得更明显,你可以检查defined?(:value_from_spec)并引发错误。(

这里有一个注入该值的规范,并读取共享上下文对它的转换:

describe 'passing values to shared context with let()' do
  # "customization block"
  include_context 'a context' do
    # set value_from_spec here
    let(:value_from_spec) { 1 }
  end
  describe 'the context' do
    it 'should read the passed value in a let() block' do
      expect(a_value_from_context).to eq(0)
    end
    it 'should read the passed value in a before() block' do
      expect(@another_value_from_context).to eq(2)
    end
  end
end

由于它总是返回相同的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上。

相关内容

  • 没有找到相关文章

最新更新