如何测试所需的 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)
}
在我的习惯中 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)
}