Ruby 如何在rspec中检查对从构造函数调用的方法的调用?
如果我有一个构造函数调用另一个函数的类,我如何检查它是否被调用以及调用的次数是否正确Ruby 如何在rspec中检查对从构造函数调用的方法的调用?,ruby,rspec,Ruby,Rspec,如果我有一个构造函数调用另一个函数的类,我如何检查它是否被调用以及调用的次数是否正确 class MyClass def initialize(count) count.times{self.do_something} end def do_something # whatever end end 我想说 n = 4 MyClass.new(n).should_receive(:do_something).exactly(n).times n = 2 MyC
class MyClass
def initialize(count)
count.times{self.do_something}
end
def do_something
# whatever
end
end
我想说
n = 4
MyClass.new(n).should_receive(:do_something).exactly(n).times
n = 2
MyClass.new(n).should_receive(:do_something).exactly(n).times
但这失败了,因为“应该接收”之前就发生了“做某事”的调用(至少我认为这就是原因)
或者从构造函数调用这样的东西,我应该重构,这是错误的吗
另外,这个问题与这个问题非常相似:
但我希望在过去的5年里,答案会比手动实现一个存根的
新的调用更好。期望值应该放在期望满足它们的代码之前
MyClass.any_instance.should_receive(:do_something).exactly(1).time
MyClass.new
那应该行。这是我想到的最好的,但我不喜欢:
在类中创建一个新方法,该方法在已分配但尚未初始化的对象上运行块。我把它放在我的spec文件的之前的块中,但可能有更好的地方:
class Class
def rspec_new(*params, &block)
o = allocate
yield(o) if block
o.__send__(:initialize, *params)
return o
end
end
那么就这样称呼它:
MyClass.rspec_new(n){|obj| obj.should_receive(:do_something).exactly(n).times}
它似乎可以工作,但不能将块传递给构造函数。至少不像你平时那样。这就是为什么我没有覆盖常规的new
方法 另一个答案是使用rspec间谍。这里的问题是,您必须为您希望在事后对其进行需求的方法创建一个模拟。事实证明这并不难,但你仍然需要列举它们。和_call_original
是使实现不变的魔力
MyClass.any_instance.stub(:method_name).and_call_original
那么你可以说:
MyClass.new(4).should have_received(:method_name).exactly(4).times
不过,我仍然希望找到一种不需要您枚举方法的方法。执行此操作的新语法如下:
allow_any_instance_of(ExampleClass).to receive(:example_method).and_return("Example")
expect_any_instance_of(ExampleClass).to receive(:example_method).and_return("Example")
但我不想在任何情况下使用它。我想把它放在这个特殊的例子上。我可能不知道我将有多少个实例,每个实例都应该能够得到一个呼叫,一些实例可能会得到另一个金额(对不起,这不在我的示例中)-更新的示例。我知道这是人为的,但我尽量不发布太多的代码。你的do\u some
方法是否在做一些复杂的事情?在我看来,你应该在初始化后测试对象的状态,而不是期望在初始化时调用方法。是的,这是我问题的一部分,我想问的是我是否应该重构。如果我不能很容易地找到答案,那我就只能这么做了。在这一点上,这是一个骄傲的问题,不管什么是“最好的”:)同意,你也给了我一些东西要弄清楚。如果我能想出点什么,我会更新答案:)我发布了一个关于我所做的事情的答案,效果很好,但没有我想要的那么干净。
allow_any_instance_of(ExampleClass).to receive(:example_method).and_return("Example")
expect_any_instance_of(ExampleClass).to receive(:example_method).and_return("Example")