我在MVVM環境中爲視圖模型生成Xcode代碼覆蓋率時遇到了一個問題。Swift MVVM測試策略和代碼覆蓋率問題
我們的基本設置視圖控制器發出請求到視圖模型,而這又要求對會談到web服務的數據管理方法。
我想到了我的想法是創建一個繼承的實際數據管理器和覆蓋由VM調用的函數一個假數據管理器測試視圖模型相當優雅的方式。
的問題是,這個工作,虛擬機必須在應用目標和測試目標的一部分。這樣做的明顯副作用是,即使單元測試通過,也不會爲屬於兩個或更多目標的項目生成代碼覆蓋率。代碼覆蓋在項目中啓用。
這裏是摘錄視圖模型:
import Foundation
class BoosViewModel: BaseViewModel {
convenience override init() {
self.init(dataManager: BoosDataManager(), andModel: nil)
}
func getUnlinkedBoos(_ cardType: CardType) {
(dataManager as! BoosDataManager).getUnlinkedBoos(cardType) { result, error in
...stuff happens here...
}
}
}
...和數據管理
class BoosDataManager: DataManager {
static let SharedInstance: BoosDataManager = {
var manager = BoosDataManager()
return manager
}()
func getUnlinkedBoos(_ cardType: CardType = .loyalty, completion: @escaping ((_ result: BoosModel?, _ error: NSError?) -> Void)) {
...stuff happens here...
}
}
...和測試
class BoosViewModelTests: XCTestCase {
func testGetUnlinkedBoosHappyPath() {
class FauxDataManager: BoosDataManager {
override func getUnlinkedBoos(_ cardType: CardType = .loyalty, completion: @escaping ((_ result: BoosModel?, _ error: NSError?) -> Void)) {
...stuff happens here...
}
}
let viewModel = BoosViewModel()
let dataManager = FauxDataManager()
viewModel.dataManager = dataManager
viewModel.getUnlinkedBoos(.loyalty)
XCTAssertTrue(testObserver.updated)
XCTAssertEqual(testObserver.newViewModel.getBoos().count, 1)
}
}
正如我前面提到的此場景中的單元測試已成功完成,但單元覆蓋不會生成。
我有,我實際創建已使用的測試外部假數據管理器類舊的測試中,被測類不是測試目標的一部分,並且覆蓋工作正常。
缺點是我必須創建多個數據管理器來處理其返回的特定情況。如果我無法封裝類,我需要創建一堆快速的數據管理器,每個場景都有一個。
這就是爲什麼我想出了內部類。
現在,如果我從測試目標中刪除測試下的視圖模型,問題就出現了。在完成此操作後,我將@testable import BoosApp添加到單元測試中,以便可以解決待測視圖模型。當我這樣做,我得到以下錯誤:
無法投類型的值 'BoosTests.BoosViewModelTests(testGetUnlinkedBoosHappyPath() - >())(FauxDataManager#1)。'(0x11f673d18)到「噓聲。 BoosDataManager'(0x10444b128)。 年08月30 20點43分01秒收費[19025]:無法投型的值 'BoosTests.BoosViewModelTests(testGetUnlinkedBoosHappyPath() - >())(FauxDataManager#1)。'(0x11f673d18)到 'Boos.BoosDataManager'( 0x10444b128)。
我不確定我錯過了什麼。有沒有辦法讓這個場景工作,或者我堅持在測試代碼之外創建多個數據管理器?