2016-03-08 82 views
0

我只是手動發現了一個遷移錯誤。我在模型中添加了一個新字段,並忘記將其添加到控制器的 _params方法中。結果新字段沒有被保存到數據庫中。在Rails中自動測試模型

一旦我注意到問題,就足以解決問題,但它讓我想知道是否有方法在測試中檢測到這一點。我會想象一個像解析模式並生成一組測試以確保所有字段都可以被寫入並且可以讀回相同數據的gem。

這是可以(或是)完成的事情嗎?到目前爲止,我的搜索引起了我很多有趣的閱讀,但不是像這樣的寶石...

+0

如果您要求人們找到第三方庫來執行您想要的操作,請注意此類請求不屬於Stack Overflow主題。請參閱[Stack Overflow幫助文件](http://www.stackoverflow.com/help)瞭解更多信息。如果你只是問你想要的是否可能,我很確定。也許這可能是你願意爲社區做貢獻的寶石。 – MarsAtomic

回答

2

這是可以寫你想要什麼。遍歷模型中的所有字段,生成反映這些字段的參數,然後在控制器上運行功能測試。問題是測試是脆弱的。如果你實際上不希望所有的字段都可以通過params寫出來呢?如果您在標準模式之外的另一個控制器中引用模型,該怎麼辦?你將如何處理能夠通過不同驗證的生成數據?你要麼必須確保你的應用程序只能以某種方式寫入,否則這個測試將變得越來越複雜,以處理額外的邊界情況。

我認爲測試中的解決方案是試圖保持簡單;意識到你已經改變了系統,並且由於這種改變,相應的測試需要更新。在這種情況下,您需要更新受該模型影響的功能和單元測試。如果您嚴格遵守測試驅動設計,您將首先更新測試以產生失敗的測試,然後實施更改。因此,希望在這種情況下更新的功能測試將失敗。

在測試之外,您可能需要查看棉絨。本質上,你問的是,如果你傳遞給對象的方法的參數與簽名不匹配,你是否可以捕獲錯誤。當完全解析代碼時(即在靜態類型環境中編譯),這更具可捕獲性。

編輯 - 我跳過了LINTING的一個步驟,因爲您還必須以某種方式編寫代碼,以使LINTER能夠捕獲它,例如更明確地傳遞給它的方法和參數。

+0

寫得很好的答案。雖然像Rubucop這樣的linders很擅長捕捉不良的習慣和常見的東西,但我並不真正瞭解linter在這種情況下會有什麼幫助,因爲你基本上都在研究所有采用'(hash = {},&block)'的ActiveRecord方法。編碼錯誤。 – max

+1

我想建議一種可能的自動化方法來「免費」捕捉這些類型的錯誤,這是OP想要的,並且首先讓Linter分析代碼出現。我認爲我更多地將其視爲一種探索OP的方式,以防OP不熟悉。我想到的解決方案是改變編碼風格並且更加明確,比如用明確的參數定義你自己的保存方法。在這種情況下,如果您沒有傳遞正確數量的參數,則可以捕獲一條棉絨。無可否認,這會導致樣板代碼並且看起來更像Java,所以......不是Rails的方式。 –

1

您可能想要考慮這樣的寶石可能不存在,因爲它在現實生活中並不實用或不實用。

從Active Record提供的反射方法中獲取模型列非常簡單。是的,你可以用它理論上自動運行循環中的一堆測試。

但實際上它只是不會削減它。在現實生活中,你不希望每列都是可分配的。這就是爲什麼你首先使用質量保護的原因。

並補充說明模型具有的各種約束和數據類型的複雜性。你最終會遇到一些非常複雜的事情,只會增加一些有限的測試。

如果您發現自己忽略了質量分配保護的屬性,則應該嘗試通過功能測試或集成測試覆蓋控制器的該部分。

class ArticlesControllerTest < ActionController::TestCase 

    def valid_attributes 
    { 
     title: 'How to test like a Rockstar', 
     content: 'Bla bla bla' 
    } 
    end 

    test "created article should have the correct attributes" do 
    post :create, article: valid_attributes 
    article = Article.last 

    valid_attributes.keys.each do |key| 
     assert_equals article[key], valid_attributes[key] 
    end 
    end 
end