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

标签 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

在使用共享代码的规范文件中:
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 docs对此不是很清楚,但是您可以通过传递包含 let() 的 block 来注入(inject)其他值调用include_context .规范传递的“自定义 block ”将首先被评估,并且可用于在共享上下文中声明的代码。

这是一个共享上下文,取决于包含它的规范 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)并引发错误。)

这是一个注入(inject)该值的规范,并读取共享上下文的转换:

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

关于ruby-on-rails - RSpec 3.5 将参数传递给 shared_context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38793494/

相关文章:

ruby-on-rails - 产品型号为 : Rspec tell me that "Trait not registered" 的 FactoryGirl

ruby-on-rails - RSpec + Jasmine Node

javascript - Ruby/JS 如何在提交按钮后重新加载页面?

mysql - 使用模型搜索特定字段

ruby-on-rails - 使用OR和AND搜索查询多列以应用过滤器

ruby-on-rails - FactoryGirl 序列破坏了我的 rspec 测试(我认为)

ruby-on-rails - 规范文件加载顺序问题 : in `find_and_eval_shared' : Could not find shared examples

ruby-on-rails - 除非明确添加 :type => :controller,否则 RSpec Controller 规范不起作用

ruby-on-rails - RSpec 失败(未定义方法 `id' 为 nil :NilClass ) with has_many through model

mysql - rails应用中不同电脑访问数据库