我偶然发现了一个奇怪的行为,却无法弄清楚我在做什么错。我希望有人能启发我。
在Rails应用程序中进行测试时,我试图对Redis客户端进行存根。因此,我正在使用MockRedis宝石。我已经用单个类方法RedisFactory
创建了一个.create
类,我想使用一个可选的MockRedis
实例对它进行存根,如下所示:
def stub_redis(mock_redis = MockRedis.new)
RedisFactory.stub :create, mock_redis { yield }
end
这没有用,总是抛出ArgumentError in Foo#Bar wrong number of arguments (0 for 1)
。进一步的调试显示,在RedisFactory.create 'foo'
块内调用stub
导致错误'foo' is no method on instance of MockRedis::Database
。
但是,我已经可以使用下面的代码片段使用lambda函数来 catch 传入的参数来解决此问题:
def stub_redis(mock_redis = MockRedis.new)
RedisFactory.stub(:create, ->(*_args) { mock_redis }) { yield }
end
有人可以解释这种行为吗?
答案 0 :(得分:1)
到目前为止,MiniTest会通过检查是否对val_or_callable
做出响应来尝试猜测传递的Proc
是否为call
,参见:
不幸的是,在这种特定情况下,Redis
以及传递的MockRedis
实例都提供了执行Redis命令的通用call
方法,请参见:
您已经找到正确的解决方法。在这种情况下,您唯一的机会是显式使用stub
的proc版本。
注意:在Ruby中,有些社区使用def call
作为ServiceObjects的模式,而使用minitest的stub
可能会很困难。在seattlerb/minitest中打开一个问题可能是个好主意。