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

时间:2018-09-06 12:54:20

标签: swift xcode unit-testing 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为代码覆盖提供了以下结果:

xcode code coverage not 100%

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

是否有任何方法可以正确地告诉Xcode绝对不应采用代码路径,因此就代码覆盖范围而言,完全可以忽略它?还是在需要对单元测试异常进行生成时有更好的模式可以遵循?

1 个答案:

答案 0 :(得分:1)

正如评论中提到的那样,您应该期望单元测试代码没有完全覆盖;特别是对于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")
}