RSpec 3.5 将参数传递给 shared_context
RSpec 3.5 pass argument to 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)
建议?感谢任何帮助。
因为它总是 return 相同 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.
RSpec docs 对此不是很清楚,但是您可以通过将包含 let()
调用的块传递给 include_context
来注入其他值。规范传递的 "customization block" 将首先被评估,并且可用于在共享上下文中声明的代码。
这是一个取决于规格的共享上下文,包括 let()
一个值,value_from_spec
,然后设置更多的值,一个通过 let()
,一个通过 a 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
我有这段代码,我想在多个规范中重复使用:
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)
建议?感谢任何帮助。
因为它总是 return 相同 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.
RSpec docs 对此不是很清楚,但是您可以通过将包含 let()
调用的块传递给 include_context
来注入其他值。规范传递的 "customization block" 将首先被评估,并且可用于在共享上下文中声明的代码。
这是一个取决于规格的共享上下文,包括 let()
一个值,value_from_spec
,然后设置更多的值,一个通过 let()
,一个通过 a 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