我正在寫我的第一個iOS單元測試(Xcode 5,iOS 6),並發現單元測試的結果因我最近在模擬器中所做的不同而異。例如。我在模擬器的聯繫人列表中單擊一個用戶,現在我的UserDefaults中的「最近的聯繫人」數據比以前多了一個對象,即使我正在運行單元測試。不應該NSUserDefault是單元測試的乾淨版嗎?
對於單元測試,它不是乾淨的隨機用戶默認數據(我習慣了用自己的乾淨數據庫進行RoR測試)。此外,我可能想要測試特定的狀態,比如有空的「近期聯繫人」數據。
從這裏看相關的問題,我似乎有些可能的答案,我不滿意。
- 模擬UserDefaults的單元測試!我將不得不修改許多現有的類,以便我可以注入這個模擬。
- 在setUp方法中清除或自定義UserDefaults!但那時在手動測試中辛苦創建的數據將不復存在。
- 在setUp方法中清除或自定義UserDefaults 然後在tearDown中恢復這些值!哎喲。
這些似乎是不必要的複雜的東西,應該是單元測試的標準做法。我不想在每個單元測試中重複自己。所以,我的問題是:
- 我是否缺少一些有關UserDefaults從ad-hoc模擬器測試到單元測試運行持續的方式?
- 是否有一種可配置的方式來解決這個問題,比如說,設置單元測試目標的UserDefaults具有不同的存儲位置的方式要比使用模擬器進行手動測試時的不同?
- 失敗的是,有沒有一個優雅的方式來做到這一點的代碼?
- 例如,我可以從XCTestCase繼承一個MyAppTestCase對象,並覆蓋setUp和tearDown方法,以便始終預留並恢復UserDefaults。這是一個好主意嗎?
你不應該單元測試用戶的默認值,因爲這是你沒有直接控制的東西。單元測試應該在原子軟件單元本身上工作 - >不應該涉及其他類或服務。你的方法聽起來更像集成測試。後者通常會使用嘲弄的界面。 – Till
我想你誤解了我的問題直到。如何進行單元測試而不用拉入我無法直接控制的東西?我不打算用實際值拉入用戶默認值。 – LisaD
另一種解決方案是使用像OCMock這樣的隔離框架。添加一個所謂的seam作爲NSUserDefaults類型的屬性。被測試的類將使用存儲在該屬性中的standardUserDefaults進行初始化。在你的測試中,你可以用模擬/存根覆蓋默認對象。 –