如何在 100% 代码覆盖率的 Xcode 单元测试中编写 do {} catch {}

How to write do {} catch {} in Xcode unit test with 100% code coverage

我是单元测试的新手,我希望尽可能实现接近 100% 的代码覆盖率,do {} catch {} 模式让我在尝试实现该目标时感到悲伤。

给定这段代码:

func testUrlRequest_WithAuthenticationNoToken_ExpectingAuthenticationFailure() {
        let mockController = MockAuthenticationController()
        mockController.token = nil
        Server.authenticationController = mockController
        do {
            _ = try Server.urlRequestWithHeaders(to: arbitraryEndpoint, excludeBearerToken: false)
            XCTFail("Expected throw when no token is present")
        } catch {
            XCTAssertEqual(error as? Server.Errors, .authenticationFailure)
        }
    }

Server.urlRequestwithHeaders() 方法正确地抛出一个被 catch {} 块捕获的错误,但是 Xcode 给我这个代码覆盖率的结果:

似乎它有两个问题,首先是 XCTFail() 永远不会被执行的警告(红色虚线警告),然后是与代码中最后一个“}”匹配的 0 红色覆盖率,所以我假设它是一些自动生成的 return 永远不会执行的代码。

有什么方法可以正确地告诉 Xcode 绝对不希望采用代码路径,因此就代码覆盖率而言忽略它?或者当您需要生成单元测试异常时是否有更好的模式可以遵循?

如评论中所述,您应该预料到您的单元测试代码不会完全覆盖;特别是 XCTFail 电话。单元测试的整个目标是 永远不会碰到那条线

即使您重组源代码以将 XCTFail 带到其他地方,您仍然打算让它永远不会执行。您可以再次使用 XCTAssertEqual 来完成更多的代码覆盖率。

func testUrlRequest_WithAuthenticationNoToken_ExpectingAuthenticationFailure() {
    let mockController = MockAuthenticationController()
    mockController.token = nil
    Server.authenticationController = mockController
    var failed = false
    do {
        _ = try Server.urlRequestWithHeaders(to: arbitraryEndpoint, excludeBearerToken: false)
    } catch {
        XCTAssertEqual(error as? Server.Errors, .authenticationFailure)
        failed = true
    }
    XCTAssertEqual(failed, true, "Expected throw when no token is present")
}