2015-12-09 70 views
1

簡短版本:我在數據庫中的表之間有一長串外鍵,所有必需/非空,這意味着我必須在7個不同的表中創建記錄工廠女孩,在我不需要他們大多數的情況下。有沒有什麼好辦法解決這個問題?使用FactoryGirl/rspec避免長外鍵鏈

長版本:我正在爲銷售商品的公司開發應用程序。所以,例如。史密斯籌碼公司打電話給他們說:「我們有一種新的'夏日燒烤'風味,並希望在澳大利亞各地的這200家Coles商店內建立結束過道特色顯示器。」該公司組織休閒工作者在每家商店執行該工作。

命名法:
一個「作業」是涵蓋範圍廣泛的請求 - 例如「建通道夏季BBQ顯示的末尾」。工作有很多任務。
a 「任務」是員工在單一商店中執行的一項工作。
所以,一個任務屬於一個員工和一個商店。

長外鍵鏈是:任務>商店>郊區>郵編>次區域>區域>國家

當測試工作和任務模式,我需要創建任務,這意味着在這6個其它創造紀錄表,我寧願避免。

+1

您是否需要創建任務,或者您可以將它們存根? – richessler

+0

當測試模型時,它可能是殘留任何其他模型和關聯的最佳實踐。這將使你的測試更能抵抗變化,但不會有效。 – BroiSatse

+0

存根可以解決我的一些情況下的問題,但不是全部。 –

回答

2

由於你有外鍵,並且它們在你的數據庫中不是空的,我的建議是禁用你的測試的外鍵檢查,然後用任何東西填充你的外鍵。這樣你就不需要創建相關的db記錄,如果它們不是你的測試所必需的。

下面是如何做到這一點的RSpec的

https://gist.github.com/myronmarston/61380bb4500b4d85dd3f

而對於SQLite的語法是PRAGMA foreign_keys = OFF;/PRAGMA foreign_keys = ON;

+0

更新內容:總體而言,我發現它比它的價值更麻煩,我認爲最好的方法是不用擔心並保留長期的外鍵鏈。你的測試會慢一點,但你會活下去。 –

1

你可以把任務一個很好的例子 - 通過使用>商店外鍵連接表。 store_tasks基本上只保存兩個外鍵:一個用於任務,另一個用於存儲。

所以,你最終會得到任務< - StoreTask - >銷售 - > ...

這樣,你可以測試任何你需要獨立的任務。

唯一的缺點是你可以在數據庫中表示一個'孤立'任務。這是不理想的(反對使它不可能代表非法狀態),但是我認爲比按照Rob的建議禁用所有外鍵的問題更少。

我總是用我在生產中使用的同一個數據庫進行測試。數據庫具有不同的強制規則和語義,並且可能會在生產失敗的情況下通過測試。我有時候也能夠使用數據庫特有的功能:Postgres對JSON,窗口函數,全文搜索等有很大的支持,我寧願擁抱而不是瞄準最低公分母。有一個不同的數據庫進行測試意味着你不能這樣做。

+0

注意:使用連接表方法並強制任務只屬於一個存儲,您需要store_tasks上task_id上的唯一索引。 –

+0

我絕對使用相同的數據庫進行測試和prod。我也可以看到爲了測試目的而禁用數據庫約束的潛在問題 - 儘管在這個階段(進入項目3年),引入連接表也不是微不足道的。現在就開始使用Robs解決方案,但明天在旅途中會問幾個問題! –

+0

此外,雖然禁用數據庫限制進行測試似乎是一個壞主意,但更改應用程序設計也是一個壞主意,特別是在測試期間創建更少的db記錄。我改變的動機是讓測試更快一點(即不創建不需要的db記錄),而不是讓事情本身「更可測試」。所以,僅僅爲了提高測試速度而改變設計並不完全適合我。 –