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

如何在RSpec测试中实现依赖注入?解决代码块注入报错

解决RSpec共享示例中块注入的LocalJumpError问题

你遇到的LocalJumpError: no block given (yield)是因为RSpec的shared_examples不会自动捕获你传给it_behaves_like的块——普通Ruby方法的yield逻辑在这里不适用,RSpec有自己的上下文作用域规则。要实现你想要的"依赖注入",也就是把特定场景的代码注入到共享示例的登录成功上下文里,可以用显式传递块并在目标上下文里执行的方式。

正确实现方式

1. 修改共享示例,显式接收并执行块

首先调整action requiring proper user logged in to be successful共享示例,让它接收块参数,并在登录成功的上下文里执行这个块:

RSpec.shared_examples "action requiring proper user logged in to be successful" do |action, &block|
  context "- when the required logged user is logged in" do
    # 先统一处理登录逻辑(这里根据你的实际需求调整,比如登录指定的required_user)
    before(:each) do
      login(required_user)
    end

    # 执行传入的自定义场景代码
    instance_eval(&block) if block_given?
  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

2. 调用共享示例时传入自定义块

在changing status共享示例里,保持你原来的块写法即可,现在块会被正确传递并注入到登录成功的上下文里:

RSpec.shared_examples "changing status" do |arguments|
  # ... 你的其他前置逻辑 ...

  it_behaves_like "action requiring proper user logged in to be successful", action do
    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

为什么这个方案可行?

  • 我们通过&block把块显式作为参数传递给共享示例,避免了RSpec作用域导致的块丢失问题。
  • instance_eval(&block)会在- when the required logged user is logged in这个上下文的作用域里执行块内容,这样块里的所有context和it都会被嵌套到这个成功登录的上下文下面,完美实现了你想要的逻辑分离和复用。
  • 登录逻辑被统一放在共享示例里,保证了所有复用这个示例的测试都遵循相同的登录前置条件,避免重复代码。

内容的提问来源于stack exchange,提问作者Karol Selak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:59:56