如何在不使用 eval 方法的情况下使用参数化代码与 RSpec 共享示例进行测试?



我在RSpec中有一个共享示例,用于测试SMS发送。在我的应用程序中,我有几个发送短信的方法,所以我想参数化我测试的代码,以便我可以将我共享的示例用于我的所有方法。完成我发现的唯一方法是使用eval函数:

RSpec.shared_examples "sending an sms" do |action_code|
it "sends an sms" do
eval(action_code)
expect(WebMock).to have_requested(**my_request**).with(**my_body**)
end
end

所以我可以像这样使用这个例子:

it_behaves_like "sending an sms",
"post :accept, params: { id: reservation.id }"
it_behaves_like "sending an sms",
"post :create, params: reservation_attributes"

如何在不使用eval功能的情况下实现此目的?我尝试将模式与yield命令一起使用,但由于范围的原因,它不起作用:

失败/错误:发布:创建,参数:reservation_attributesreservation_attributes在示例组(例如describecontext块(上不可用。它只能从单个示例中获得(例如it块(或来自在示例范围内运行的构造(例如beforelet等(。

实际上,在您的情况下,动作和参数可以作为参数传递到共享示例中:

RSpec.shared_examples "sending an sms" do |action, params|
it "sends an sms" do
post action, params: params
expect(WebMock).to have_requested(**my_request**).with(**my_body**)
end
end

并称为:

it_behaves_like "sending an sms", :accept, { id: reservation.id }
it_behaves_like "sending an sms", :create, reservation_attributes

或者,您可以为每个块定义单独的操作

RSpec.shared_examples "sending an sms" do
it "sends an sms" do
action
expect(WebMock).to have_requested(**my_request**).with(**my_body**)
end
end
it_behaves_like "sending an sms" do
let(:action) { post :accept, params: { id: reservation.id } }
end
it_behaves_like "sending an sms" do
let(:action) { post :create, params: reservation_attributes }
end

最新更新