Swift:XCTest代理/协议回调(单元测试)

13

我需要为委托/协议回调创建一些单元测试。这是我尝试测试的实现示例:

protocol SomethingWithNumbersDelegate: class {

    func somethingWithDelegate(results:Int)
}

class SomethingWithNumbers {
    var delegate: SomethingWithNumbersDelegate? = nil
    func doAsyncStuffWithNumbers(number:Int)  {

        var numbers = Int()
        /*
         doing some with the input
         */
        self.delegate?.somethingWithDelegate(results: numbers)
    }
}

我还没有找到创建单元测试(XCTest)来测试委托响应的方法。

如果您能提供帮助,我将不胜感激。

1个回答

32
您可以使用XCTestExpectation工具来实现此功能,例如:
class NumbersTest: XCTestCase, SomethingWithNumbersDelegate {

    func testAsynchronousNumbers() {
        numbersExpectation = expectation(description: "Numbers")

        let numbers = SomethingWithNumbers()
        numbers.delegate = self
        numbers.doAsyncStuffWithNumbers(number: 123)

        // Waits 100 seconds for results.
        // Timeout is always treated as a test failure.
        waitForExpectations(timeout: 100)
        XCTAssertEqual(self.results, 456)
    }

    private var numbersExpectation: XCTestExpectation!
    private var results: Int!

    func somethingWithDelegate(results: Int) {
        self.results = results
        numbersExpectation.fulfill()
    }
}

随着Xcode 6的引入,expectations让异步测试变得更加容易。XCTestCase上的辅助方法可以创建expectations,例如:

func expectation(description: String) -> XCTestExpectation

创建并返回与测试用例关联的期望值。


更新。对于运行Xcode 9的用户,这是等待给定XCTestExpectation实例的首选习惯用语(即代替旧的waitForExpectations方法):

wait(for: [numbersExpectation], timeout: 100)

@user2924482 例如,将timeout参数从10秒增加到100秒。顺便说一下,我也更新了答案。 - Paulo Mattos
当然,你的函数doAsyncStuffWithNumbers最终必须完成才能使测试成功 :) - Paulo Mattos
是的,我错过了这个类DelegateTest: XCTestCase,SomethingWithNumbersDelegate。现在它正在工作。感谢您的帮助。 - user2924482
很棒的回答! 有人能告诉我为什么在numbersExpectation和result中使用了“private”吗? - Yash Bedi
1
@YashBedi 由于这些属性仅在NumbersTests类内部需要使用,因此使用private来限制仅在该类中使用。如果您创建XCTestCase的另一个子类,则不应需要访问这些属性。没有其他类型应该访问这些属性,因此最好使用private - Nick Kohrn
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接