Minitest - 从另一个实例方法中调用模拟实例方法

Minitest - calling a mocked instance method from within another instance method

我在 Minitest::Mock 中遇到了一些奇怪的行为,无法弄清楚背后的原因。

说我有这个 class A 有一个方法 b 调用方法 c:

class A

  def b
    c
  end

  def c
    1
  end

end

我想将 c 方法模拟为 return 2 而不是 1:

require 'minitest/autorun'

a = Minitest::Mock.new(A.new)
a.expect(:c, 2)

但由于某些原因 b 仍然 returns 1:

> a.b
=> 1 

显然直接调用 c 会起作用:

> a.c
=> 2
> a.c
MockExpectationError: No more expects available for :c: []

为什么在实例中调用时 c 上的期望没有被调用?

这就是 Minitest::Mock 的工作方式;模拟对象是 A 的 "real" 实例的包装器,并且定义的期望在到达该实例之前拦截方法调用。 (其他方法,如 b,没有定义预期,会在不受影响的情况下转发——尽管它们仍然会通过模拟。)

当实例在内部进行方法调用时,它们会直接转到 self,而不是通过模拟包装器返回,因此它们会正常分派,没有被拦截的机会。


找到了一个很棒的 gem 解决了这个问题:

https://github.com/bogdanvlviv/minitest-mock_expectations

assert_called a, :c do
  a.b
end