如何测试所需的 init(coder:)?

How to test required init(coder:)?

在我的习惯中 class WLNetworkClient 我必须实现这样的方法:

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

我不需要使用它,但我想测试它以实现 100% 的代码覆盖率。你知道如何实现吗?

我尝试了以下方法但没有成功:

let nc = WLNetworkClient(coder: NSCoder())
XCTAssertNotNil(nc)

是对你有帮助的答案:

let cd = NSKeyedUnarchiver(forReadingWithData: NSMutableData())
let c = CustomTextField(coder:cd)

生产代码:

required init?(coder: NSCoder) {
    return nil
}

测试:

func testInitWithCoder() {
    let archiverData = NSMutableData()
    let archiver = NSKeyedArchiver(forWritingWithMutableData: archiverData)
    let someView = SomeView(coder: archiver)
    XCTAssertNil(someView)
}

由于需要初始化器returns nil并且没有使用编码器,所以上面的代码可以简化为:

func testInitWithCoder() {
    let someView = SomeView(coder: NSCoder())
    XCTAssertNil(someView)
}

Rudolf Adamkovič 的回答仍在与 Swift 4 合作:

required init?(coder aDecoder: NSCoder) {
    return nil
}

func testInitWithCoder() {
    // 1. Arrange
    let archiver = NSKeyedArchiver(forWritingWith: NSMutableData())

    // 2. Action
    let viewController = ViewController(coder: archiver)

    // 3. Assert
    XCTAssertNil(viewController)
}

我将 Rudolf 的回答与 Liz 的建议相结合,并得出以下解决方案:

let viewController = SomeTableViewController(
    presenter: SomePresenterMock(),
    coder: NSKeyedUnarchiver(forReadingWith: Data())) 

XCTAssert(viewController?.tableView.numberOfSections == 1)

这里的关键是使用 NSKeyedUnarchiver(forReadingWith: Data()) 作为模拟编码器,否则测试会因 NSInvalidArgumentException 而崩溃。

我使用改进的 Rudolf's Adamkovič 答案:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

func test_initWithCoder() {
    let object = SomeView()
    let data = NSKeyedArchiver.archivedData(withRootObject: object)
    let coder = NSKeyedUnarchiver(forReadingWith: data)
    let sut = SomeView(coder: coder)
    XCTAssertNotNil(sut)
}

之前的答案似乎都在Swift 5.

之后失效了

我设法修改了 答案并使其像这样工作:

func testInitWithCoder() {
    // Given
    let object = SomeView()
    let data = try! NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
    let coder = try! NSKeyedUnarchiver(forReadingFrom: data)

    // When
    let sut = SomeView(coder: coder)

    // Then
    XCTAssertNotNil(sut)
}