簡體   English   中英

如何單元測試`viewDidLoad()`

[英]How to unit test `viewDidLoad()`

在 iOS 上對UIViewController.viewDidLoad()方法進行單元測試時,每個人最喜歡的注入依賴項的方式是什么?

鑒於我的實現是:

class MyViewController: UIViewController {

    var service: Service = Service()

    override func viewDidLoad() {
        super.viewDidLoad()
        service.load()
    }
}

我的測試課是這樣的:

class MyViewController Tests: XCTestCase {

     var vc: MyViewController!
     var serviceMock = ServiceMock()

    override func setUp() {
       super.setUp()
       let storyboard = UIStoryboard(name: "Main", bundle: nil)
       vc = storyboard.instantiateViewController(withIdentifier: "MyViewController") as! MyViewController
       vc.service = serviceMock
    }
}

func testThatServiceIsCalled() {

       XCTAssertTrue(serviceMock.loadCalled)
 }

這里明顯的問題是viewDidLoad()在我實例化 viewController 時被調用,並且測試失敗,因為模擬沒有正確注入。

有什么解決辦法嗎?

為什么需要使用storyboard來創建視圖控制器?

這行不通?

func testThatServiceIsCalled() {
  let vc = MyViewController()
  vc.service = serviceMock
  vc.viewDidLoad()

  XCTAssertTrue(serviceMock.loadCalled)
}

TL;DR 你不應該像這樣對 UI 相關的方法進行單元測試。

控制器和視圖不適合單元測試,原因很簡單,它們通常涉及反映在屏幕上的操作,因此(非常)難以測試。 快照測試或 UI 自動化測試是這兩個 MVC 組件的更好候選者。

編寫良好的控制器不包含業務邏輯,它將 UI 內容委托給視圖,並將業務操作委托給其模型。 考慮到這一點,模型應該是進行單元測試的模型。

現在,如果你真的想斷言你的服務被正確的方法調用,你可以將你的 VC 設置為根視圖控制器,這應該確保loadView方法被調用,這應該觸發viewDidLoad一個:

func testThatServiceIsCalled() {
    let window = UIWindow(frame:  UIScreen.main.bounds)
    window.makeKeyAndVisible()
    window.rootViewController = vc
    XCTAssertTrue(serviceMock.loadCalled)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM