17

我正在尝试存根某个类的任何实例。我需要存根fetch方法,它用一些数据填充自我。

如何访问self变量、修改变量并返回fetch方法?

MyObject.any_instance.stub(:fetch) { self }

不返回MyObject实例。

也许,模拟在这种情况下更有用。不幸的是,我还没有理解它们。

4

2 回答 2

16

有一个开放的 rspec-mocks 问题可以解决这个问题。我希望在某个时候解决它,但是以一种不会破坏any_instance与块实现一起使用的现有规范套件的方式添加它并不简单,因为我们将开始产生一个额外的参数(例如对象实例)。

总体而言,any_instance在某些情况下可以派上用场,但它有点异味,如果您能找到模拟或存根单个实例的方法,您通常会遇到更少的问题。

这是我尚未测试但应该可以解决的解决方法:

orig_new = MyObject.method(:new)
MyObject.stub(:new) do |*args, &block|
  orig_new.call(*args, &block).tap do |instance|
    instance.stub(:fetch) { instance }
  end
end

本质上,我们在any_instance这里通过挂钩来模拟,MyObject.new以便我们可以fetch对每个实例化的新实例进行存根。

综上所述,“倾听您的测试”很重要,并且,当某些东西难以测试时,请考虑一下您的设计所代表的内容,而不是立即使用any_instance. 您最初的问题没有为我提供足够的背景信息来推测您的设计,但这绝对是我在需要这样做时开始的地方。

于 2012-12-15T19:40:00.517 回答
2

据我所知,由于某种原因,这似乎是不可能的。我检查了当前的rspec-mocks实现,实际调用存根实现的方法似乎如下:

# lib/rspec/mocks/message_expectation.rb:450
def call_implementation(*args, &block)
    @implementation.arity == 0 ? @implementation.call(&block) : @implementation.call(*args, &block)
end

看起来,该块只是由自身调用而不是通过instance_eval. 也许还有另一种技术可以实现您想要的,毕竟我无论如何都不是 RSpec 专家。

于 2012-12-15T18:06:57.540 回答