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

时间:2018-05-07 12:15:58

标签: ruby-on-rails rspec dry

我在RSpec中有一个共享示例,用于测试短信发送。在我的应用程序中,我有几个方法发送短信,所以我想参数化我测试的代码,以便我可以使用我的共享示例我的所有方法。我发现的唯一方法就是使用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命令一起使用,但由于范围原因它无效:

  

失败/错误:post:create,params:reservation_attributes     reservation_attributes在示例组(例如describecontext块)上不可用。它仅在单个示例(例如it块)中或从示例范围内运行的构造(例如beforelet等)中提供。

1 个答案:

答案 0 :(得分:3)

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

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

或者您可以定义separate action for every block

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