2015-06-20 40 views
2

采用摩卡嘲笑或存根远跨网络进入一个功能非常有用:如何在单元测试中用其他方法临时替换方法?

def test_something 
    NetworkClass.stub(:fetch_something, "contrived example") 

    assert_equal "contrived example", NetworkClass.fetch_something 
end 

但更多的时候,我的网络交叉功能需要一定的投入,以及输入影响是什么函数返回。对于我的单元测试,我只准备了一个Hash,其中包含我的测试套件需要运行的输入和输出。问题是,现在我不能再使用Mochas .stub.expects,因为它们不允许我替换实际执行某些操作的函数。

目前我在做这样的事情:

def setup 
    @subject = NetworkClass.new 

    test_data = fetch_test_data 

    @subject.define_singleton_method(:fetch_something) { |input| 
    test_data[input] or fail "Unexpected stub input: #{input}" 
    } 
end 

但这永久改变的主题,所以我不能使用此方法桩模块函数或类方法。

有没有办法用另一种方法“临时”替换方法,就像摩卡的.stub一样简单?

如果有人想告诉我,这是一个不好的方式来测试并告诉我一个更好的方法,我想我也会接受这个答案。这一直在困扰我一段时间。为了避免这种


一个显而易见的方法是存根在考虑特定输入每个测试功能的方法,但是在我看来,像很多额外的“样板”的测试代码没有实际的好处。另外,通过这种方式,我可以确定,我不会忘记在某处存储方法,并且每次运行我的测试套件时都会意外地通过网络。

+0

我想答案是声明另一个类相同的接口。至少我是这么做的。 – Casey

回答

1

就像你说的,如果你知道测试中的输入是什么,你可能仍然可以使用摩卡的功能。

NetworkClass.stub(:fetch_something).with(input).returns(test_data[input])

这仅fetch_something时调用正确的输入将被执行。您可以通过不同的输入以这种方式创建几个存根。

一般来说,这应该不成问题,因为您的测试应该是可预测和可重复的。这意味着每个独立的测试用例应该运行相同的代码路径,并因此为您的NetworkClass触发相同的参数。每个测试用例都应该运行一个代码路径并尽可能地集中。

编辑

不知道你的测试框架是什么,但应该有每个测试用例之前安装和拆卸机制。这样你可以使用你的方法,并在每个测试用例之后恢复类。

-1

在RSpec的3你可以使用allow

allow(NetworkClass).to receive(:fetch_something).with(input) { test_data[input] } 

或(更多的颗粒测试)

allow(NetworkClass).to receive(:fetch_something) do |arg| 
    expect(arg).to eql test_data[input] 
end 
相关问题