Minitest 存根将块传递给模拟实例
Minitest stub passing block to mock instance
我偶然发现了一个奇怪的行为,但一直无法弄清楚我做错了什么。希望有人能赐教。
我在 Rails 应用程序的测试期间试图对 Redis 客户端进行存根。因此我使用的是 MockRedis gem。我用单一 class 方法 .create
创建了一个 RedisFactory
class,我想用一个可选的 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)
。一些进一步的调试表明,在 stub
块中调用 RedisFactory.create 'foo'
会导致错误 '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
有人可以解释这种行为吗?
截至目前,MiniTest 尝试通过检查它是否响应 call
来猜测传递的 val_or_callable
是否为 Proc
,参见:
- https://apidock.com/ruby/Proc/call
- https://github.com/seattlerb/minitest/blob/b84b8176930bacb4d70d6bef476b1ea0f7c94977/lib/minitest/mock.rb#L226
不幸的是,在这种特定情况下 Redis
以及传递的 MockRedis
-实例都提供了一个通用的 call
-方法来执行 Redis 命令,cf.:
您已经找到了正确的解决方法。在这种情况下,您唯一的机会是显式使用 stub
.
的 proc-version
注意:有些社区使用 def call
作为 ServiceObjects in Ruby which may have a difficult time using minitest's stub
. It is probably a good idea to open an issue in seattlerb/minitest 的模式。
我偶然发现了一个奇怪的行为,但一直无法弄清楚我做错了什么。希望有人能赐教。
我在 Rails 应用程序的测试期间试图对 Redis 客户端进行存根。因此我使用的是 MockRedis gem。我用单一 class 方法 .create
创建了一个 RedisFactory
class,我想用一个可选的 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)
。一些进一步的调试表明,在 stub
块中调用 RedisFactory.create 'foo'
会导致错误 '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
有人可以解释这种行为吗?
截至目前,MiniTest 尝试通过检查它是否响应 call
来猜测传递的 val_or_callable
是否为 Proc
,参见:
- https://apidock.com/ruby/Proc/call
- https://github.com/seattlerb/minitest/blob/b84b8176930bacb4d70d6bef476b1ea0f7c94977/lib/minitest/mock.rb#L226
不幸的是,在这种特定情况下 Redis
以及传递的 MockRedis
-实例都提供了一个通用的 call
-方法来执行 Redis 命令,cf.:
您已经找到了正确的解决方法。在这种情况下,您唯一的机会是显式使用 stub
.
注意:有些社区使用 def call
作为 ServiceObjects in Ruby which may have a difficult time using minitest's stub
. It is probably a good idea to open an issue in seattlerb/minitest 的模式。