ruby - RSpec 是否允许我使用匹配器选择模拟?
问题描述
我有很多电话
Kernel.open(url).read
在一些遗留代码中,我试图在大规模重构之前模拟特征测试。
我不喜欢参数被忽略的方式
allow_any_instance_of(Kernel).to(receive_message_chain(:open, :read)
.and_return(return_value))
所以我把它换成了
def stub_kernel_open_read(args: '[arg1, arg2, k: v, etc]', returning:)
allow_any_instance_of(Kernel).to(receive(:open).with(*args)).and_return(double.tap { |d|
allow(d).to(receive(:read)).and_return(returning)
})
end
但我发现我遇到了这些错误:
"http://my-fake-server/whatever" received :open with unexpected arguments
expected: ("http://my-fake-server/whatever", {:http_basic_authentication=>["asdf", "asdf"]})
got: ({:http_basic_authentication=>["asdf", "asdf"]})
Diff:
@@ -1,3 +1,2 @@
-["http://my-fake-server/whatever",
- {:http_basic_authentication=>["asdf", "asdf"]}]
+[{:http_basic_authentication=>["asdf", "asdf"]}]
Please stub a default value first if message might be received with other args as well.
所以我发现如果我将我的存根扩展到这个:
allow_any_instance_of(Kernel).to(receive(:open).with(*args)) { |instance|
return double.tap { |d|
allow(d).to(receive(:read)) {
return returning
}
}
}
然后instance
具有 URL 的值。就目前而言,这很好,我可以建立一个允许的 URL 列表,但感觉很糟糕。
有没有类似的东西
allow_any_instance_of(Kernel).that(eq('http://whatever')).to(receive(:open))
还是我只是在完全错误的胡同里吠叫?
显然,我可以使用全局搜索替换来包装Kernel.open(url).read
代码,并正确地模拟该全局,但如果可能的话,我宁愿避免这种情况。
解决方案
AFAIU 你的问题是正确的,你需要这样的东西,告诉模拟行为“正常”:
allow(Kernel).to receive(:open).with(url).and_return(stub)
allow(Kernel).to receive(:open).with(anything).and_call_original # I can't check now, but there's a chance this one should go first, but I doubt it
那么就
allow(stub).to receive(:read).and_return('something')
如果你必须模拟Kernel.open
更多的 URL,它会变得有点乱,但原理是一样的
allow(Kernel).to receive(:open).with(first_url).and_return(first_stub)
allow(Kernel).to receive(:open).with(second_url).and_return(second_stub)
allow(Kernel).to receive(:open).with(anything).and_call_original # I can't check now, but there's a chance this one should go first
allow(first_stub).to receive(:read).and_return('something')
allow(second_stub).to receive(:read).and_return('something else')
除非我完全错过了你问题的重点?
推荐阅读
- multithreading - 如何在等待用户输入时使用 Discord bot 打印消息
- c# - 实体类型
不是当前上下文模型的一部分 - python - 在python中将所有表格从word转移到excel
- python - Python返回一个按相同键对值进行分组的字典
- javascript - 在功能组件内调用 useStore 但出现错误
- python - 每当我使用命令时,它都会显示“找不到命令”或根本不说任何内容
- c# - Linq 返回 Nullable 对象必须有一个值,因为有些列是 null
- r - 对于相同大小的两个数据帧 df 和 logicaldf,命令 df[logicaldf, ] 在 R 中执行什么?
- c# - 身份服务器 4 会话/cookie 问题
- javascript - Chrome 扩展获取/设置数组显示在控制台中,但不在 html dom 中