You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否向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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:43:20