2008-09-16 49 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