我正在重构我的测试。我认为如果适当的用户登录并且我的成功行为的逻辑,我应该分离负责处理的逻辑。所以我开始用不成功的上下文创建一个共享示例,但是我在这一刻陷入困境:
RSpec.shared_examples "changing status" do |arguments|
/* ... */
it_behaves_like "action requiring proper user logged in to be successful", action
context "- when the required logged user is logged in" do
before(:each) do
/* ... */
end
context "and when the reservation has an allowed status" do
/* ... */
end
context "and when the reservation has a not allowed status" do
/* ... */
end
end
end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action|
context "- when the logged in user is not the required logged user" do
before(:each) do
login(incidental_user)
end
it_behaves_like "unsuccessful attempt to change the reservation", action
end
context "- when there's no user logged in" do
it_behaves_like "unsuccessful attempt to change the reservation", action
end
end
所以,我想将我的上下文"when the required logged user is logged in"
中的代码注入到我的共享示例中,以使其干净。我尝试使用匿名代码块和yield
关键字:
RSpec.shared_examples "changing status" do |arguments|
/* ... */
it_behaves_like "action requiring proper user logged in to be successful", action do
before(:each) do
/* ... */
end
context "and when the reservation has an allowed status" do
/* ... */
end
context "and when the reservation has a not allowed status" do
/* ... */
end
end
end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action|
context "- when the required logged user is logged in" do
yield
end
context "- when the logged in user is not the required logged user" do
before(:each) do
login(incidental_user)
end
it_behaves_like "unsuccessful attempt to change the reservation", action
end
context "- when there's no user logged in" do
it_behaves_like "unsuccessful attempt to change the reservation", action
end
end
但不幸的是它收到了这个错误:
LocalJumpError:没有给定块(yield)
那么,我该怎么做呢?
答案 0 :(得分:0)
有趣的问题。
你可以在一个封装的例子中做到这一点,但还有另一种,IMO更清晰的方式:
为正面和负面测试单独shared_example
s。你已经解决了这个问题,所以你做得很好(只需更改名称,明确它是一组负面的测试)。
积极的人可以这样:
RSpec.shared_examples 'restricted action with logged in user' do
before { login(authorized_user) }
specify do
expect_stuff_typical_for_logged_in_user
# e.g. expect(response).to be_success
end
end
然后在您的规范中将其包含在include_examples
中,就像这样
context do
include_examples 'restricted action with logged in user'
# you're "inside" the context of included examples so you can
# write down extra expectations specific for each action
end
可能存在一个案例,即您的积极部分没有共同的期望,只是设置背景 - 您可以考虑使用shared_context清楚地表达您的意图。
你可以在一个像这样的共享例子中把它全部搞砸了:
RSpec.shared_examples "action requiring proper user logged in to be successful" do
# set up the context for positive scenarios, so you can include it with
# `include_examples` and be "inside" this context
before { login(authorized_user) }
context "- when the logged in user is not the required logged user" do
before(:each) do
login(incidental_user)
end
it_behaves_like "unsuccessful attempt to change the reservation"
end
context "- when there's no user logged in" do
before { log_out_people }
it_behaves_like "unsuccessful attempt to change the reservation"
end
end
这有两个问题。首先,你设置一个积极的上下文,然后你必须在负面的例子中撤消它(感觉smelly)。 其次,它可能并不明显规范中发生了什么。 它们看起来像这样:
context do
include_examples 'action requiring proper user logged in to be successful'
specify do
expect(response).not_to be_redirect
end
context 'when user have not seen changes TOS' do
before { }
specify do
expect(session[:notice]).to eq 'Please read new TOS'
end
end
它根本不清楚,负面的例子都被涵盖了。
然后,如果在任何地方你需要对否定案例的自定义期望 - 你仍然需要拆分它们。
您可以决定以任何一种方式了解权衡。
答案 1 :(得分:0)
最后我用lambda解决了我的问题:
RSpec.shared_examples "changing status" do |arguments|
/* ... */
it_behaves_like "action requiring proper user logged in to be successful", action, -> {
before(:each) do
/* ... */
end
context "and when the reservation has an allowed status" do
/* ... */
end
context "and when the reservation has a not allowed status" do
/* ... */
end
}
end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action, successful_behavior|
context "- when the required logged user is logged in" do
successful_behavior.()
end
context "- when the logged in user is not the required logged user" do
before(:each) do
login(incidental_user)
end
it_behaves_like "unsuccessful attempt to change the reservation", action
end
context "- when there's no user logged in" do
it_behaves_like "unsuccessful attempt to change the reservation", action
end
end