2008-09-16 52 views
3

我是一位Java开发人员,喜欢Ruby。我了解到,由于Ruby的元编程设施,我的单元测试变得更干净,而且我不需要讨厌的嘲笑框架。我有一门课需要File班的服务,在我的测试中,我不想碰我真正的文件系统。在Java中,我会使用一些虚拟文件系统来更容易的“接缝”来传递伪造对象,但是在Ruby中显然是过度的。与Java世界相比,我所提出的似乎已经非常好。在我的测试类我有一个可选的构造函数参数:Ruby中的嘲讽构造函数

def initialize(file_class=File) 

当我需要我的类中打开文件,然后我就可以做到这一点:

@file_class.open(filename) 

和呼叫转移到任何真正的文件类,或者在我的单元测试的情况下,它会转到一个不接触文件系统的假类。我知道用metaprogramming必须有更好的方法来做到这一点吗?

回答

11

摩卡(http://mocha.rubyforge.org/)是一个非常好的红宝石嘲弄库。取决于你实际想要测试的内容(例如,如果你想伪造File.new调用来避免文件系统依赖,或者如果你想验证正确的参数传入File.new),你可以做这样的事情:

 

require 'mocha' 

mock_file_obj = mock("My Mock File") do 
    stubs(:some_instance_method).returns("foo") 
end 

File.stubs(:new).with(is_a(String)).returns(mock_file_obj) 
 
+0

是的,我只是不想使用嘲笑库。你真的需要Ruby吗? – auramo 2008-09-16 13:43:47

1

如果你已经概述了,我会建议你在做什么似乎很好。我知道这是詹姆斯米德(摩卡的作者)所倡导的一种技巧。为了它,不需要进行元编程。 Here's what James has to say about it(以及其他可以尝试的技术列表)

1

这对我来说是一个特别困难的挑战。在this question的帮助下,我收到了一些额外的工作,下面是我的解决方案。

# lib/real_thing.rb 
class RealThing 
    def initialize a, b, c 
    # ... 
    end 
end 

# test/test_real_thing.rb 
class TestRealThing < MiniTest::Unit::TestCase 

    class Fake < RealThing; end 

    def test_real_thing_initializer 
    fake = mock() 
    Fake.expects(:new).with(1, 2, 3).returns(fake) 
    assert_equal fake, Fake.new(1, 2, 3) 
    end 

end