9

I have the following code (trying to avoid implicit unwrapping):

class MyTests: XCTestCase {

    var viewController: ViewController

}

But I'm getting the following error:

Class 'MyTests' has no initializers

I fixed with this:

class MyTests: XCTestCase {

    var viewController: ViewController

    override init() {
        self.viewController = ViewController()
        super.init()
    }
}

Would be a issue using init() in XCTest class?
I'm using Swift 4, Xcode 9.2.

4

3 回答 3

16

我了解您希望避免隐式展开,但不幸的是(除非您想通过编写自己的测试运行程序来解决问题),您无法控制在运行测试时调用哪个初始化程序。

如您所知,您可以通过隐式展开并设置属性的值来解决此问题setUp(),在每次测试之前都会调用该值,因此您可以确保在测试期间该属性不会为 nil。这是相对安全的。

class MyTests: XCTestCase {

    var viewController: ViewController!

    override function setUp() {
        super.setUp()
        self.viewController = ViewController()
    }
}

或者,您可以制作 property lazy,这意味着它不必被隐式解包。这意味着该属性不必在对象初始化期间进行初始化,因此您无需编写新的初始化程序,但会在第一次访问时对其进行初始化。

class MyTests: XCTestCase {

    lazy var viewController: ViewController = {
        return ViewController()
    }()
}
于 2018-02-16T07:44:09.667 回答
2

编写 XCTest 时无需编写初始化程序。

XCTestCase提供在执行实际测试之前准备测试项目的方法。

将 viewController 声明为显式展开(以避免隐式展开),如下所示。

class MyTests: XCTestCase {

    var viewController: ViewController!

}

始终在每个XCTestCase类中覆盖以下 2 个方法。

setUp是在实际测试执行之前准备变量。初始化视图控制器setUp

override func setUp() {
        super.setUp()
        self.viewController = ViewController()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

tearDown是在完成测试后释放变量和其他资源。在tearDown.

override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class
        self.viewController = nil
        super.tearDown()
    }
于 2018-02-15T12:38:56.693 回答
0

实际上,setup()在每个测试方法调用中调用。

/*!
 * @method -setUp
 * Setup method called before the invocation of each test method in the class.
 */
- (void)setUp;

那么,为什么你需要为当前XCTests子类中的 3 个测试方法创建 viewController,比方说 3 次?您可以尝试在 XCTests 子类之外声明您的变量

于 2018-11-13T13:31:37.190 回答