2012-02-10 20 views
1

我的應用程序的核心是一個引擎,它將一個問題規範,編碼爲數據結構,並生成我們需要的結果。實例化spec數據結構有兩種方法:解析腳本或通過Rails UI。在Rails的情況下,數據結構是數據庫中的模型對象,在腳本情況下,它是模型類的內存中實例。引擎處於獨立的寶石中,因此腳本驅動的進程可以獨立運行而不需要Rails。Ruby中的協調類合同

我的問題是如何確保兩個數據結構,Rails數據庫模型和內存模型,履行相同的合同。如果這是Java,那麼我會編寫一個模型類將實現的接口,但在Ruby中,我依賴於鴨子輸入。我將爲每個模型進行測試,但只有一個測試套件會更加乾燥。但是,我不明白如何分享測試,但是,在寶石項目和rails項目之間。

關鍵的挑戰是:假設我向Rails模型添加了一個責任,我如何保證將相應的責任添加到腳本內存模型中,反之亦然?

回答

1

我想你應該創建一個模塊,其職責是檢查接收器類是否包含所需的方法。

事情是這樣的:

module Contract 
    STATIC_METHODS = [ :class_foo ] 
    INSTANCE_METHODS = [ :instance_foo ] 

    def self.included(receiver) 
    STATIC_METHODS.each do |method| 
     raise("missing class method #{method}") unless receiver.respond_to? method 
    end 
    INSTANCE_METHODS.each do |method| 
     raise("missing instance method #{method}") unless receiver.instance_methods.include? method.to_s 
    end 
    end 
end 

class YourClass 
    def self.class_foo 
    end 

    def instance_foo 

    end 

    include Contract 
end 

謹防包括Contract你的文件的末尾,否則就會很自然地失敗(方法不會被定義)。

關於你的測試,你應該創建一些常見的測試,並在你的類的東西,如運行它們:it_should_behave_like

+0

感謝。在純粹的實踐層面上,你會在哪裏放置這個模塊,以便它可以在兩個項目中使用?這是測試代碼,所以將它看作自己的寶石,看起來很奇怪(對我來說)。但是,我不確定Ruby提供的其他什麼機制包括遠程代碼(即對於包含的項目不是本地的)。 – 2012-02-10 15:30:06

+0

一個乾淨的方法是開發一些sbmodule:http://book.git-scm.com/5_submodules.html。否則,把文件放在任何你想要的地方,並提供一個絕對路徑。 – apneadiving 2012-02-10 15:32:15