能否向Rails RSpec的it_behaves_like传递代码块扩展断言?
问题
我定义了如下shared_examples:
shared_examples 'success' do let(:params) { key: "value" } it "returns data" do post "/api/users", params: params expect(response.status).to eq(201) end end
当我使用it_behaves_like调用该共享示例时,能否传递一个代码块来扩展断言列表?
比如我尝试这么写:
it_behaves_like "success" do expect(response['id']).to eq(1) end
期望RSpec最终执行的逻辑是:
it "returns data" do post "/api/users", params: params expect(response.status).to eq(201) expect(response['id']).to eq(1) end
但当前写法达不到预期效果,请问该怎么实现这个需求?是否可行?
解决方案
完全可行,你只需要调整shared_examples的定义,让它支持接收并执行传入的代码块即可,具体实现如下:
修改共享示例定义
给shared_examples添加块参数,然后在原有的it代码块内,判断如果有传入块就执行它:
shared_examples 'success' do |&block| let(:params) { key: "value" } it "returns data" do post "/api/users", params: params expect(response.status).to eq(201) # 执行调用时传入的扩展断言逻辑 instance_eval(&block) if block_given? end end
调用共享示例
现在你原来的调用写法就能正常工作了:
it_behaves_like "success" do expect(response['id']).to eq(1) end
执行时,RSpec会把你传入的代码块嵌入到原有的it逻辑中,实现断言扩展的效果。
进阶:自定义示例名称
如果需要给扩展后的示例设置自定义名称,可以给shared_examples增加一个名称参数:
shared_examples 'success' do |example_name = "returns data", &block| let(:params) { key: "value" } it example_name do post "/api/users", params: params expect(response.status).to eq(201) instance_eval(&block) if block_given? end end
调用时可以指定示例名称:
it_behaves_like "success", "returns user data with correct id" do expect(response['id']).to eq(1) end
内容的提问来源于stack exchange,提问作者manh.vu
相关产品推荐
相关产品推荐

