LoginSignup
51
32

More than 5 years have passed since last update.

[iOS、Swift] ユニットテストの時に、任意のタイミングでViewDidLoad()、ViewWill(Did)Appear()、ViewWill(Did)Disappear()を呼び出す方法

Last updated at Posted at 2017-11-10

忘れがちなので備忘も兼ねてまとめておきます。

事前準備

以下のようなView Controller(Initial View Controller)を作成します。

HogeViewController.swift

import UIKit

class HogeViewController: UIViewController {

    // ViewDidLoad()用フラグ
    var isViewDidLoadCalled = false

    // ViewWill(Did)Appear()用フラグ
    var isViewWillAppearCalled = false
    var isViewDidAppearCalled = false

    // ViewWill(Did)Disappear()用フラグ
    var isViewWillDisappearCalled = false
    var isViewDidDisappearCalled = false

    // MARK: - View Controller Lifecycle Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        self.isViewDidLoadCalled = true
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.isViewWillAppearCalled = true
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.isViewDidAppearCalled = true
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.isViewWillDisappearCalled = true
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.isViewDidDisappearCalled = true
    }
}

次に、このView Controllerをテストするファイルを作成し、以下のようなセットアップを行います。

HogeViewControllerTests.swift

import XCTest
@testable import InvokeVCLifecycleMethods

class HogeViewControllerTests: XCTestCase {

    var hogeVC: HogeViewController!

    override func setUp() {
        super.setUp()

        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        hogeVC = storyboard.instantiateInitialViewController() as! HogeViewController
    }

    override func tearDown() {
        super.tearDown()
    }

    func test_ViewDidLoad_Called() {
        XCTAssertTrue(hogeVC.isViewDidLoadCalled)
    }

    func test_ViewWillAndDidAppear_Called() {
        XCTAssertTrue(hogeVC.isViewWillAppearCalled)
        XCTAssertTrue(hogeVC.isViewDidAppearCalled)
    }

    func test_ViewWillAndDidDisappear_Called() {
        XCTAssertTrue(hogeVC.isViewWillDisappearCalled)
        XCTAssertTrue(hogeVC.isViewDidDisappearCalled)
    }

}

この状態でテストを実行すると、全てのテストがFailします。

all_failed.png

これで事前準備は完了です。

View Controller LifeCycleメソッドを呼び出す

それでは早速、各種メソッドを呼び出していきましょう。

ViewDidLoad()

ViewDidLoad()は、View Controllerのviewプロパティにアクセスすることで呼び出せます。

[追記] @kazuhiro4949さんより、viewへのアクセスではなくloadViewIfNeeded()ViewDidLoad()を呼び出す方法を教えていただきました。ありがとうございます!

    func test_ViewDidLoad_Called() {
        // ViewDidLoad()を呼び出す
        hogeVC.loadViewIfNeeded()

        XCTAssertTrue(hogeVC.isViewDidLoadCalled)
    }

結果

pass1.png

Passしました。

ViewWill(Did)Appear()

ViewWillAppear()は、UIViewControllerにbeginAppearanceTransition(_:animated:)というインスタンスメソッドが用意されており、その第一引数(_ isAppearing: Bool)をtrueにして呼ぶことで呼び出せます。ViewDidAppear()は、そのインスタンスメソッドを呼んだ後にendAppearanceTransition()を呼ぶことで呼び出せます。

        // ViewWillAppear()を呼び出す(第一引数をtrueにする)
        hogeVC.beginAppearanceTransition(true, animated: false)
        // ViewDidAppear()を呼び出す
        hogeVC.endAppearanceTransition()

結果

pass_appear.png

これもPassしました。

ViewWill(Did)Disappear()

ViewWillDisappear()は、先程のbeginAppearanceTransition(_:animated:)の第一引数(_ isAppearing: Bool)をfalseにして呼ぶことで呼び出せます。ViewDidDisappear()は、その後にendAppearanceTransition()を呼ぶことで呼び出せます。

    func test_ViewWillAndDidDisappear_Called() {
        // ViewWillDisappear()を呼び出す(第一引数をfalseにする)
        hogeVC.beginAppearanceTransition(false, animated: false)
        // ViewDidDisappear()を呼び出す
        hogeVC.endAppearanceTransition()

        XCTAssertTrue(hogeVC.isViewWillDisappearCalled)
        XCTAssertTrue(hogeVC.isViewDidDisappearCalled)
    }

結果

pass_disappear.png

全てPassしました。

ユニットテストを書く時にご活用ください。

参考

Work with View Controllers
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html)

[追記] loadViewIfNeeded()
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621446-loadviewifneeded

beginAppearanceTransition(_:animated:)
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621387-beginappearancetransition

endAppearanceTransition()
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621503-endappearancetransition

iOS: The One Weird Trick For Testing View Controllers in Swift

Testing in Swift

51
32
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
32