SwiftでUIAlertControllerをテストする方法
4943 ワード
最近、Objective-Cでcontrol swizzlingを使用してUIAlertControllerをテストする記事を読みました.このような文章はいつもcontrol swizzlingを使わなくても同じものをテストできる方法を探しています.swizzlingは開発者の非常に強力なツールであることは知っていますが、個人的にはできるだけ避けることができます.実際、最近の6年間、私は1つのアプリケーションでswizzlingを使っただけです.だから私たちは今swizzlingを使わずにテストを実現できると信じています.
では、問題が発生しました.どのようにしてSwiftでswizzlingを使用しないでUIalertControllerをテストしますか?
まず、テストするコードから始めましょう.Storyboardにボタンを追加しました.(私がStoryboardを使っているのは、コードでインタフェースを書きたくない仲間にもっと直感的に感じさせるためです)このボタンを押すと、タイトル、メッセージの内容、そしてOKとキャンセル(Cancel)の2つのボタンが表示されます.
次はこのコードです.
なお、この例では、弾窓動作は具体的な操作を行わず、ユニットテストを検証できることを示しているだけである.
簡単なテストを始めましょう.この弾窓コントローラのタイトルとメッセージの内容をテストします.
テストのコードは次のとおりです.
sutをルートビューコントローラに設定する必要があります.そうしないと、ビューコントローラはこのポップアップビューコントローラをポップアップできません.
UIalertControllerテストタイトルを追加するコードは次のとおりです.
これは簡単です.UIAlertControllerのキャンセルボタンをテストします.ここで問題があります.弾窓動作の閉パッケージを取得できません.そのため、このhandlerを格納し、テストで呼び出すために、弾窓動作が予想通りかどうかを確認するために、弾窓動作をシミュレートする必要があります.テスト・インスタンスに次のクラスを追加します.
このシミュレーションクラスの主な仕事はhandlerブロックをキャプチャして後で使用することである.このシミュレーションのクラスを実装コードに挿入する必要があります.ビューコントローラのコードを次のように変更します.
クラス変数`Action`を追加し、`UIalertActionに設定した.self`.この変数は弾窓動作を初期化する際に使用します.これにより、テスト時に書き換えることができます.このように:
まず私たちはこの弾窓動作を挿入しました.その後、コードポップアップウィンドウビューコントローラを呼び出します.レンダリングされたビューコントローラからキャンセル動作を取得し,キャプチャされたhandlerブロックの呼び出しに成功した.最後のステップは、現在の動作が私たちが予想していたのと同じかどうかを断言することです.
このように、swizzlingを使用せずにUIalertView Controlをテストする方法です.
以上は、SwiftでUIAlertControllerをテストする方法についてですが、皆さんに役に立つと思います.
では、問題が発生しました.どのようにしてSwiftでswizzlingを使用しないでUIalertControllerをテストしますか?
まず、テストするコードから始めましょう.Storyboardにボタンを追加しました.(私がStoryboardを使っているのは、コードでインタフェースを書きたくない仲間にもっと直感的に感じさせるためです)このボタンを押すと、タイトル、メッセージの内容、そしてOKとキャンセル(Cancel)の2つのボタンが表示されます.
次はこのコードです.
import UIKit
class ViewController: UIViewController {
var actionString: String?
@IBAction func showAlert(sender: UIButton) {
let alertViewController = UIAlertController(title: "Test Title", message: "Message", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default) { (action) -> Void in
self.actionString = "OK"
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in
self.actionString = "Cancel"
}
alertViewController.addAction(cancelAction)
alertViewController.addAction(okAction)
presentViewController(alertViewController, animated: true, completion: nil)
}
}
なお、この例では、弾窓動作は具体的な操作を行わず、ユニットテストを検証できることを示しているだけである.
簡単なテストを始めましょう.この弾窓コントローラのタイトルとメッセージの内容をテストします.
テストのコードは次のとおりです.
import XCTest
@testable import TestingAlertExperiment
class TestingAlertExperimentTests: XCTestCase {
var sut: ViewController!
override func setUp() {
super.setUp()
sut = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as! ViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = sut
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
}
```
sutをルートビューコントローラに設定する必要があります.そうしないと、ビューコントローラはこのポップアップビューコントローラをポップアップできません.
UIalertControllerテストタイトルを追加するコードは次のとおりです.
```Swift
func testAlert_HasTitle() {
sut.showAlert(UIButton())
XCTAssertTrue(sut.presentedViewController is UIAlertController)
XCTAssertEqual(sut.presentedViewController?.title, "Test Title")
}
```
これは簡単です.UIAlertControllerのキャンセルボタンをテストします.ここで問題があります.弾窓動作の閉パッケージを取得できません.そのため、このhandlerを格納し、テストで呼び出すために、弾窓動作が予想通りかどうかを確認するために、弾窓動作をシミュレートする必要があります.テスト・インスタンスに次のクラスを追加します.
```Swift
class MockAlertAction : UIAlertAction {
typealias Handler = ((UIAlertAction) -> Void)
var handler: Handler?
var mockTitle: String?
var mockStyle: UIAlertActionStyle
convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void)?) {
self.init()
mockTitle = title
mockStyle = style
self.handler = handler
}
override init() {
mockStyle = .Default
super.init()
}
}
このシミュレーションクラスの主な仕事はhandlerブロックをキャプチャして後で使用することである.このシミュレーションのクラスを実装コードに挿入する必要があります.ビューコントローラのコードを次のように変更します.
import UIKit
class ViewController: UIViewController {
var Action = UIAlertAction.self
var actionString: String?
@IBAction func showAlert(sender: UIButton) {
let alertViewController = UIAlertController(title: "Test Title", message: "Message", preferredStyle: .Alert)
let okAction = Action.init(title: "OK", style: .Default) { (action) -> Void in
self.actionString = "OK"
}
let cancelAction = Action.init(title: "Cancel", style: .Cancel) { (action) -> Void in
self.actionString = "Cancel"
}
alertViewController.addAction(cancelAction)
alertViewController.addAction(okAction)
presentViewController(alertViewController, animated: true, completion: nil)
}
}
```
クラス変数`Action`を追加し、`UIalertActionに設定した.self`.この変数は弾窓動作を初期化する際に使用します.これにより、テスト時に書き換えることができます.このように:
```Swift
func testAlert_FirstActionStoresCancel() {
sut.Action = MockAlertAction.self
sut.showAlert(UIButton())
let alertController = sut.presentedViewController as! UIAlertController
let action = alertController.actions.first as! MockAlertAction
action.handler!(action)
XCTAssertEqual(sut.actionString, "Cancel")
}
まず私たちはこの弾窓動作を挿入しました.その後、コードポップアップウィンドウビューコントローラを呼び出します.レンダリングされたビューコントローラからキャンセル動作を取得し,キャプチャされたhandlerブロックの呼び出しに成功した.最後のステップは、現在の動作が私たちが予想していたのと同じかどうかを断言することです.
このように、swizzlingを使用せずにUIalertView Controlをテストする方法です.
以上は、SwiftでUIAlertControllerをテストする方法についてですが、皆さんに役に立つと思います.