我是快速测试的新手,目前我想尝试四个测试。我有一个从 ViewController 到另一个 ViewController (searchedForViewController) 的 segue。对于这个 segue,我想测试这 4 件事:
- 是否存在标识符为“searchSegue”的 segue?
- 是否调用了 segue 然后我点击按钮搜索?
- Segue 的目的地是 SearchedForViewController
- Segue 是否将 SearchedForVC 的变量“passedString”更改为“garten”?
我在 Main.storyboard 中的 segue 看起来像这样:
我的 segue 代码如下(工作,但为了将来我只想知道如何测试):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "searchSegue" {
guard let controller = segue.destination as? SearchedForViewController
else {
return
}
controller.passedString = "garten"
}
}
目前我的测试类是空的,看起来像这样(只是加载 View ):
class ViewControllerTests: XCTestCase {
var vc: ViewController!
override func setUp() {
super.setUp()
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
vc = storyboard.instantiateViewController(withIdentifier: "test") as! ViewController
let _ = vc.view
}
func testSegueShouldExist() {
let identifiers = getSegues(ofViewController: vc)
XCTAssertEqual(identifiers.count, 1, "Segue count should equal one.")
XCTAssertTrue(identifiers.contains("searchSegue"), "Segue searchSegue should exist.")
}
func testSegueActionsThenPushSearchButton() {
// code here
}
func testSegueDirectsToSearchedForViewController() {
// code here
}
func testSeguePassedGartenAsValueToSearchedForVC() {
// call prepare and test after?
}
}
编辑我发现了如何实现 segueShouldExist。我添加了代码。它调用辅助函数:
func getSegues(ofViewController viewController: UIViewController) -> [String] {
let identifiers = (viewController.value(forKey: "storyboardSegueTemplates") as? [AnyObject])?.flatMap({ $0.value(forKey: "identifier") as? String }) ?? []
return identifiers
}
最佳答案
要使其正常工作,您需要稍微重构一下代码。
# ViewControllerTests.swift
var capturedSegue: UIStoryboardSegue?
extension ViewController {
override open func prepare(for segue: UIStoryboardSegue, sender: Any?) {
prepareSearchForVC(with: segue)
capturedSegue = segue
}
}
class ViewControllerTests: XCTestCase {
var vc: ViewController!
override func setUp() {
super.setUp()
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
vc = storyboard.instantiateInitialViewController() as! ViewController
vc.loadViewIfNeeded()
}
func testSegueShouldExist() {
let identifiers = getSegues(ofViewController: vc)
XCTAssertEqual(identifiers.count, 1, "Segue count should equal one.")
XCTAssertTrue(identifiers.contains("searchSegue"), "Segue searchSegue should exist.")
}
func testSegueActionsThenPushSearchButton() {
// Can programmatically send actions to UIControl classes
vc.searchButton.sendActions(for: .touchUpInside)
// Just makes sure any segue was called
// since there is only one in this case there's no need to be more specific
XCTAssertNotNil(capturedSegue)
}
func testSegueDirectsToSearchedForViewController() {
vc.performSegue(withIdentifier: "searchSegue", sender: nil)
// Attempts to cast the captured segue
let destination = capturedSegue?.destination as? SearchedForVC
XCTAssertNotNil(destination,
"Destination should be searched for controller")
}
func testSeguePassedGartenAsValueToSearchedForVC() {
vc.performSegue(withIdentifier: "searchSegue", sender: nil)
let destination = capturedSegue?.destination as? SearchedForVC
XCTAssertEqual(destination?.passedString, "garten")
}
func getSegues(ofViewController viewController: UIViewController) -> [String] {
let identifiers = (viewController.value(forKey: "storyboardSegueTemplates") as? [AnyObject])?.flatMap({ $0.value(forKey: "identifier") as? String }) ?? []
return identifiers
}
}
使这项工作成功的原因是将 ViewController
中的 prepare(for:,sender:)
方法从:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "searchSegue" {
guard let controller = segue.destination as? SearchedForViewController
else {
return
}
controller.passedString = "garten"
}
}
到:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
prepareSearchForVC(with: segue)
}
func prepareSearchForVC(with segue: UIStoryboardSegue) {
if segue.identifier == "searchSegue" {
guard let controller = segue.destination as? SearchedForVC
else {
return
}
controller.passedString = "garten"
}
}
希望对您有所帮助。
关于Swift:测试 Segue 是否存在,是否有正确的目的地并更改正确的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42002019/