rspec中的double方法是什么?

在rspec doc中说,我应该使用double方法来创buildtestingdouble。 但是我可以看到,即使我不使用double ,它也能正常工作。 不使用double有什么问题吗? 另外,如果我不使用双如何MyClass获取stub和其他rspec方法? 它们在rspec中运行时是否可用于所有对象?

 require 'spec_helper' class MyClass def self.run new.execute end def execute 'foo' end end describe MyClass do it 'should stub instance method' do obj = MyClass.new obj.stub(:execute).and_return('bar') obj.execute.should == 'bar' end it 'should stub class method' do MyClass.stub(:run).and_return('baz') MyClass.run.should == 'baz' end end 

编辑:我刚刚重读你的问题,并意识到我不完全回答。 留下我原来的答案,因为它是相关的,但这里是你的具体答案:

你不需要双重的原因是因为你是存根类的方法,而不是实例方法。 double仅用于处理类的实例,而不是类本身。

旧的答案,多解释一些:

如果可以的话,你应该总是使用真正的类,而不是testing双打。 这将更多地运用你的代码,使你的testing更全面。 testing双打是用于你不能或不应该使用真实物体的情况。 例如,如果一个类不能在没有外部资源(如networking或数据库)的情况下实例化,或者拥有大量的依赖关系,而只是testing使用它的东西,则可能需要创build一个双重和存根一些方法在双。

下面是一个更具体的例子:假设你正在testingMyClass ,但为了实例化MyClass ,你需要传入一个FooLogger

 mylogger = FooLogger.new myclass = MyClass.new logger: mylogger 

如果FooLogger.new打开一个系统日志套接字并立即开始发送垃圾邮件,则每次运行testing时,都会logging日志。 如果您不希望在testing期间发送垃圾邮件,则可以为FooLogger创build一个双FooLogger并在其上存储一个方法:

 mylogger = double(FooLogger) mylogger.stub(:log) myclass = MyClass.new logger: mylogger 

因为大多数精心devise的类都可以实例化而没有任何副作用,所以通常可以使用真实的对象而不是双重的方法。 还有其他一些场景,类有许多依赖关系,这使得它们很难实例化,而双打也是一种通过检查和testing你真正关心的东西的方法。

根据我的经验,需要使用double是一种代码味道,但是我们经常需要使用不容易改变的类(例如,从一个gem),所以这是您可能需要的一种工具。

使用RSpec Mocks 3.0,双打的行为已经改变。 您现在可以validation双打 ,这意味着“RSpec将检查被底层对象实际上是否存在被桩存在的方法”,但是如果底层对象或类没有被定义,则不进行检查。

validation双精度要求您详细说明doubletypes(实例,类,对象,dynamic类,部分)。 下面是一个来自RSpec Relish的例子double:

 RSpec.describe User, '#suspend!' do it 'notifies the console' do notifier = instance_double("ConsoleNotifier") expect(notifier).to receive(:notify).with("suspended as") user = User.new(notifier) user.suspend! end end