忘れがちなので備忘も兼ねてまとめておきます。
事前準備
以下のようなView Controller(Initial View Controller)を作成します。
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をテストするファイルを作成し、以下のようなセットアップを行います。
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します。
これで事前準備は完了です。
View Controller LifeCycleメソッドを呼び出す
それでは早速、各種メソッドを呼び出していきましょう。
ViewDidLoad()
ViewDidLoad()は、View Controllerのview
プロパティにアクセスすることで呼び出せます。
[追記] @kazuhiro4949さんより、view
へのアクセスではなくloadViewIfNeeded()
でViewDidLoad()
を呼び出す方法を教えていただきました。ありがとうございます!
func test_ViewDidLoad_Called() {
// ViewDidLoad()を呼び出す
hogeVC.loadViewIfNeeded()
XCTAssertTrue(hogeVC.isViewDidLoadCalled)
}
結果
Passしました。
ViewWill(Did)Appear()
ViewWillAppear()
は、UIViewControllerにbeginAppearanceTransition(_:animated:)
というインスタンスメソッドが用意されており、その第一引数(_ isAppearing: Bool
)をtrue
にして呼ぶことで呼び出せます。ViewDidAppear()
は、そのインスタンスメソッドを呼んだ後にendAppearanceTransition()
を呼ぶことで呼び出せます。
// ViewWillAppear()を呼び出す(第一引数をtrueにする)
hogeVC.beginAppearanceTransition(true, animated: false)
// ViewDidAppear()を呼び出す
hogeVC.endAppearanceTransition()
結果
これも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しました。
ユニットテストを書く時にご活用ください。
参考
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]
(https://www.natashatherobot.com/ios-testing-view-controllers-swift/)