rspec中的双重方法是什么?

gra*_*hez 38 ruby rspec mocking stub

在rspec doc中声明我应该使用double方法来创建测试double.但我可以看到,即使我不使用它也能完美运行double.不使用有什么问题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
Run Code Online (Sandbox Code Playgroud)

Jim*_*art 43

编辑:我只是重新阅读你的问题并意识到我没有完全回答它.留下原来的答案,因为它是相关的,但这是你的具体答案:

您不需要double的原因是因为您正在使用类方法,而不是实例方法. double仅用于处理类的实例,而不是类本身.

旧答案解释了更多:

你应该总是使用真正的类而不是测试双打.这将运用更多代码并使您的测试更加全面.测试双打用于您不能或不应该使用真实对象的情况.例如,如果一个类在没有命中外部资源(如网络或数据库)的情况下无法实例化,或者具有大量依赖项,并且您只是在测试使用它的东西,那么您可能希望创建一个double和stub上的一些方法.

这是一个更具体的例子:假设您正在测试MyClass,但为了实例化MyClass,您需要传入FooLogger:

mylogger = FooLogger.new
myclass = MyClass.new logger: mylogger
Run Code Online (Sandbox Code Playgroud)

如果FooLogger.new打开一个syslog套接字并立即开始发送垃圾邮件,那么每次运行测试时,您都将进行日志记录.如果您不希望在此测试期间将日志垃圾邮件,则可以为其创建一个double FooLogger并在其上存根方法:

mylogger = double(FooLogger)
mylogger.stub(:log)
myclass = MyClass.new logger: mylogger
Run Code Online (Sandbox Code Playgroud)

因为大多数设计良好的类都可以在没有任何副作用的情况下实例化,所以通常只需使用真实对象而不是双重和存根方法.在其他情况下,类具有许多依赖性,使得它们难以实例化,并且双精度是一种通过错误并测试您真正关心的事物的方法.

根据我的经验,需要使用double是代码气味,但我们经常必须使用我们无法轻易更改的类(例如来自gem),因此它是您可能不时需要的工具.

  • 确切地说,这也是我的想法.但我不知道为什么我看不到Ruby世界中使用的注入.人们更喜欢在方法中使用`new`对象,并使用像你提到的rspec`stub`这样的东西来提供虚假实例.注意点不仅仅是测试,它使代码更好.不知道为什么这种技术在Ruby世界中并不常见.对我来说,java编码器,很难切换. (2认同)