rspec中的double方法有什么用? [英] What is double method in rspec for?

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

问题描述

在rspec文档中指出,我应该使用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仅用于处理类的实例,而不是类本身.

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.

原来的答案可以再解释一遍:

在可能的情况下,应始终使用实型类,而不是测试双精度型.这将使用更多的代码,并使您的测试更加全面.测试双打用于无法或不应使用真实对象的情况.例如,如果某个类不能在不访问外部资源(例如网络或数据库)的情况下实例化,或者具有大量依赖关系,而您只是在测试使用该类的东西,则可能需要创建一个并在某些方法上添加一些方法.

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

由于大多数实例化设计良好的类都可以实例化而没有任何副作用,因此通常可以只使用实际对象而不是double,并在其上使用stub方法.在其他情况下,类具有许多依赖关系,这使得它们难以实例化,而double则是一种克服困难并测试您真正关心的事情的方法.

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中的double方法有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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