はじめに
皆様、ユニットテストされていますか?
Model周りはテストしやすいですが、ViewController周りはテストしずらいですよね。
今日は、モックを使って、UIAlertViewController(Alert)をテストする方法をご紹介します。
ユニットテストの種類
テストの種類 | 説明 |
---|---|
スタブ | メソッドの戻り値にダミーの値を返すこと |
モック | メソッドが呼ばれているか、プロパティに値がセットされているか確認すること |
パーシャルモック | 既存のクラスのうち一部のメソッドをモック化すること |
プロトコルを利用して、モック化する
UIAlertViewControllerのAlertを例に説明します。
プロトコル
DialogPresenter.swift
import UIKit
protocol DialogPresenter {
func present(title: String, message: String?, onOK: (Void -> Void),
onTopOf presenter: UIViewController)
}
OKとCancelボタン付きのアラート
OKCancelDialogPresenter.swift
import UIKit
class OKCancelDialogPresenter: DialogPresenter {
func present(title: String, message: String?, onOK: (Void -> Void),
onTopOf presentingViewController: UIViewController) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alert.addAction(cancelAction)
let okAction = UIAlertAction(title: "OK", style: .Default) { _ in onOK() }
alert.addAction(okAction)
presentingViewController.presentViewController(alert, animated: true, completion: nil)
}
}
ViewControllerから呼ぶ
ボタンが押下されたら、ダイアログを表示する
ViewController.swift
@IBAction func didTapButton(sender: UIButton) {
OKCancelDialogPresenter().present("タイトル",
message: "メッセージ",
onOK: { (Void) in
print(#function)
},
onTopOf: self)
}
モックを作る
メソッドが呼ばれたか、プロパティに正しく値がセットされているか確認する
MocDialogPresenter.swift
import UIKit
class MocDialogPresenter: DialogPresenter {
var present_wasCalled = false
var present_wasCalled_withArgs: (title: String, message: String?,
onOK: (Void -> Void), presentingVC: UIViewController)? = nil
func present(title: String, message: String?, onOK: (Void -> Void),
onTopOf presenter: UIViewController) {
present_wasCalled = true
present_wasCalled_withArgs = (title: title, message: message, onOK: onOK, presentingVC: presenter)
}
}
ユニットテストする
DialogTest.swift
import XCTest
class DialogTest: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testOKCancelDialog() {
let dialog = MocDialogPresenter()
dialog.present("タイトル",
message: "メッセージ",
onOK: { (Void) in },
onTopOf: UIViewController())
XCTAssertTrue(dialog.present_wasCalled)
XCTAssertEqual("タイトル", dialog.present_wasCalled_withArgs?.title)
XCTAssertEqual("メッセージ", dialog.present_wasCalled_withArgs?.message)
XCTAssertNotNil(dialog.present_wasCalled_withArgs?.onOK)
XCTAssertNotNil(dialog.present_wasCalled_withArgs?.presentingVC)
}
}
まとめ
プロトコルを利用してモック化する方法をご紹介しました。
ViewControllerからPresenterに切り出せる処理は、
ユニットテストしていきたいと思います。
参考記事
下記の記事を参考に纏めさせて頂きました。
大変勉強になりました。
https://realm.io/jp/news/rachel-bobbins-testing-view-controllers-quick/
https://realm.io/jp/news/tryswift-veronica-ray-real-world-mocking-swift/