rspec 中的双重方法是什么? [英] What is double method in rspec for?

查看:18
本文介绍了rspec 中的双重方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It is stated in rspec doc that I should use double method in order to create test double. But I can see that it works perfectly ok even if I don't use double. Is there anything wrong with not using double? Also if I'm not using double how MyClass gets stub and other rspec methods? Are they available for all objects when running in 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 的原因是因为您正在存根类方法,而不是实例方法.double 仅用于处理类的实例,而不是类本身.

The reason you don't need a double is because you're stubbing class methods, rather than instance methods. double is only useful for dealing with instances of the class, not the class itself.

旧答案解释了更多:

如果可以,您应该始终使用真正的类而不是测试替身.这将练习更多的代码并使您的测试更加全面.测试替身用于您不能或不应该使用真实对象的情况.例如,如果一个类不能在不访问外部资源(如网络或数据库)的情况下被实例化,或者有大量的依赖项,而你只是在测试使用它的东西,你可能想要创建一个double 并在 double 上存根一些方法.

You should always use real classes instead of test doubles when you can. This will exercise more of your code and make your tests more comprehensive. Test doubles are used in situations where you can't or shouldn't use a real object. For example, if a class can't be instantiated without hitting an external resource (like a network or a database), or has a large number of dependencies, and you're just testing something that uses it, you might want to create a double and stub some methods on the double.

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

Here's a more specific example: let's say you are testing MyClass, but in order to instantiate MyClass, you need to pass in a FooLogger:

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

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

If FooLogger.new opens a syslog socket and starts spamming it right away, every time you run your tests, you'll be logging. If you don't want to spam your logs during this test, you can instead create a double for FooLogger and stub out a method on it:

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

因为大多数设计良好的类都可以在没有任何副作用的情况下实例化,所以您通常可以只使用真实对象而不是双精度对象,并在其上使用存根方法.在其他一些场景中,类有很多依赖项,这使得它们难以实例化,而双精度数是一种绕过繁琐并测试您真正关心的东西的方法.

Because most well-designed classes can be instantiated without any side-effects, you can usually just use the real object instead of a double, and stub methods on that instead. There are other scenarios where classes have many dependencies that make them difficult to instantiate, and doubles are a way to get past the cruft and test the thing you really care about.

根据我的经验,需要使用 double 是一种代码味道,但我们经常不得不使用我们无法轻易更改的类(例如从 gem 中),因此它是您可能不时需要的工具.

In my experience, needing to use a double is a code smell, but we often have to use classes that we can't easily change (e.g. from a gem), so it's a tool you might need from time to time.

这篇关于rspec 中的双重方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆