如何用RSpec Mock实例方法调用的featureEnabled??解决空对象报错
解决RSpec Mock空对象报错问题
问题根源
控制器中@domain依赖current_account.domain,你的测试仅mock了Domain实例,但未让控制器的current_account返回这个mock对象,导致@domain为nil,触发NoMethodError。
正确的Mock配置方式
1. 核心思路
需要先mock控制器的current_account方法,让它返回一个带有domain属性的mock对象,再为这个domain对象mockfeatureEnabled?方法,确保控制器能获取到非空的@domain实例。
2. 完整测试代码示例
RSpec.describe ApiHelpers do describe "#find_matching_lists" do let(:mock_domain) { instance_double(Domain) } let(:mock_account) { instance_double(Account, domain: mock_domain) } it "正确mock featureEnabled?方法" do # 让控制器的current_account返回预设的mock账户 allow(controller).to receive(:current_account).and_return(mock_account) # 为mock domain设置featureEnabled?方法的返回值 allow(mock_domain).to receive(:featureEnabled?).with("showPages").and_return(true) # 调用要测试的控制器方法 subject.main # 可选:验证方法是否按预期被调用 expect(mock_domain).to have_received(:featureEnabled?).with("showPages") end end end
关键说明
- 使用
instance_double替代直接实例化Domain,这是RSpec推荐的测试替身方式,能自动校验被mock的方法是否真实存在,避免拼写错误。 - 必须确保控制器能获取到
current_account,否则@domain会始终为nil,这是报错的核心原因。 - 测试最后要调用目标控制器方法(如
subject.main),否则mock设置后不会触发实际调用流程,无法验证逻辑。
内容的提问来源于stack exchange,提问作者imba22
相关产品推荐
相关产品推荐

