繁体   English   中英

如何在Swift中对一个子类UIViewController进行类型转换?

[英]How to typecast a subclassed UIViewController in Swift?

我正在尝试使用storyboard在swift中测试UITableViewController的子类。 我能够获得对视图控制器的引用并将其记录下来,但我无法将其类型转换为我要测试的类,因此我无法访问方法,属性等。

掌握班级实例的正确方法是什么?

测试场景:

import XCTest
import UIKit    
class GameListControllerTest: XCTestCase {
    var storyboard = UIStoryboard(name: "Main", bundle: nil)
    var _sut: AnyObject?
    var sut: AnyObject {
        if(_sut?) {
            return _sut!
        }
        _sut = storyboard.instantiateViewControllerWithIdentifier("GameListController")
        return _sut!
    }
    override func setUp() {
        super.setUp()
        println()
        println("=================================")
        println("sut  \(sut)")
        println("view  \(sut.view)")
        println("=================================")

    }
    func testInstance() {
        var vc1 = sut as UITableViewController
        var vc2 = sut as? GameListController
        println()
        println("=================================")
        println("VC1  \(vc1)")
        println("VC2  \(vc2)")
        println("=================================")
    }
}

输出:

XCTestOutputBarrierTest Suite '_TtC15mytabletopTests22GameListControllerTest' started at 2014-06-16 06:13:30 +0000
XCTestOutputBarrierTest Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]' started.
XCTestOutputBarrier
=================================
sut  <_TtC10mytabletop18GameListController: 0xb338d50>
view  <UITableView: 0xc033800; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0xb344960>; layer = <CALayer: 0xb33c7d0>; contentOffset: {0, 0}; contentSize: {480, 0}>
=================================

=================================
VC1  <_TtC10mytabletop18GameListController: 0xb338d50>
VC2  nil
=================================
Test Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]' passed (0.007 seconds).
XCTestOutputBarrierTest Suite '_TtC15mytabletopTests22GameListControllerTest' passed at 2014-06-16 06:13:30 +0000.
     Executed 1 test, with 0 failures (0 unexpected) in 0.007 (0.010) seconds

如果我试图强制进行类型转换( sut as GameListController ),我会得到一个运行时异常。

这是正在发生的事情。 我花了几天才弄明白,但我的问题在于如何将我的类导出到目标:

文件检查器目标成员资格不正确与正确

这导致我的类的两个二进制副本,一个在app目标中,另一个在测试目标中。 如果我们更加关注日志,我们可能会注意到:

Test Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]'

以上是测试方法testInstance ,它是mytabletopTests执行上下文的一部分。 现在让我们看一下从Storyboard中提取的实例:

sut  <_TtC10mytabletop18GameListController: 0xb338d50>

这反过来又在mytabletop上下文中运行。 这解释了为什么测试无法对GameListController进行类型转换。 它知道的GameListController是在测试目标内编译的。

由于从测试目标中删除类使得我的测试用例不知道该类,现在我需要将我的app目标导入到测试用例中:

import XCTest
import UIKit
import mytabletop // LINE ADDED

class GameListControllerTest: XCTestCase {

现在,测试可以访问的唯一GameListController与故事板实例化的相同,我终于可以输入它了。 这是新的测试用例:

import XCTest
import UIKit
import mytabletop

class GameListControllerTest: XCTestCase {
    let sut: GameListController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("GameListController") as GameListController

    override func setUp() {
        super.setUp()
        UIApplication.sharedApplication().keyWindow.rootViewController = sut
        XCTAssertNotNil(sut.view)
    }

    func testInstance() {
        XCTAssertNotNil(sut)
        XCTAssertNotNil(sut.tableView) // UITableViewController property
        XCTAssertNotNil(sut.store) // instance property
        XCTAssertNotNil(sut.someButton) // outlet
    }
}

现在我能够在实例初始化期间正确地进行类型转换(滚动以查看as GameListController )。 为了强制所有出口正确绑定并且子视图相应地呈现正在运行测试的设备,我们可以使视图控制器成为应用程序的rootViewController并从中拉出视图,如上面的setUp函数所示。 甚至myCustomOutlet现在也能正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM