5

我正在用Swift编写XCTest单元测试。这个想法是在特定情况下不能调用回调。

所以我做的是

func testThatCallbackIsNotFired() {

    let expectation = expectationWithDescription("A callback is fired")
    // configure an async operation

    asyncOperation.run() { (_) -> () in
        expectation.fulfill()    // if this happens, the test must fail
    }

    waitForExpectationsWithTimeout(1) { (error: NSError?) -> Void in

        // here I expect error to be not nil,
        // which would signalize that expectation is not fulfilled,
        // which is what I expect, because callback mustn't be called
        XCTAssert(error != nil, "A callback mustn't be fired")
    }
}

调用回调时,一切正常:它失败并显示一条消息“不能触发回调”,这正是我所需要的。

但是如果期望没有实现,它会失败并说

异步等待失败:超过 1 秒的超时,未实现预期:“回调被触发”。

由于我需要的是未实现的期望,因此我不希望测试失败。

你有什么建议我可以做些什么来避免这种情况?或者,也许,我可以用不同的方式达到我的目标?谢谢。

4

2 回答 2

5

isInverted在这篇文章中使用https://www.swiftbysundell.com/posts/unit-testing-asynchronous-swift-code

class DebouncerTests: XCTestCase {
    func testPreviousClosureCancelled() {
        let debouncer = Debouncer(delay: 0.25)

        // Expectation for the closure we'e expecting to be cancelled
        let cancelExpectation = expectation(description: "Cancel")
        cancelExpectation.isInverted = true

        // Expectation for the closure we're expecting to be completed
        let completedExpectation = expectation(description: "Completed")

        debouncer.schedule {
            cancelExpectation.fulfill()
        }

        // When we schedule a new closure, the previous one should be cancelled
        debouncer.schedule {
            completedExpectation.fulfill()
        }

        // We add an extra 0.05 seconds to reduce the risk for flakiness
        waitForExpectations(timeout: 0.3, handler: nil)
    }
}
于 2019-04-02T10:52:55.140 回答
3

我遇到了同样的问题,我很生气你不能使用处理程序来覆盖 waitForExpectationsWithTimeout 的超时失败。这是我解决它的方法(Swift 2 语法):

func testThatCallbackIsNotFired() {
    expectationForPredicate(NSPredicate{(_, _) in
        struct Holder {static let startTime = CACurrentMediaTime()}

        if checkSomehowThatCallbackFired() {
            XCTFail("Callback fired when it shouldn't have.")
            return true
        }

        return Holder.startTime.distanceTo(CACurrentMediaTime()) > 1.0 // or however long you want to wait
        }, evaluatedWithObject: self, handler: nil)
    waitForExpectationsWithTimeout(2.0 /*longer than wait time above*/, handler: nil)
}
于 2015-11-01T01:25:34.233 回答