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