我打了很多电话
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
代码,并正确地模拟该全局代码,但我希望尽可能避免这种情况。