微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – 调用异步方法的方法的单元测试

我想我有这些代码行:
func reset() {
    initializeAnythingElse() {
        // AnythingElse
    }

    initializeHomeData() {
        // HomeData
    }
}

func initializeHomeData(callback: @escaping (()-> Void)) {
    getHomeConfig() {
        callback()
    }
}

func initializeAnythingElse(callback: @escaping (()-> Void)) {
    getAnythingElse() {
        callback()
    }
}

我想为该代码编写一个单元测试.对于initializeHomeData和initializeAnythingElse,我可以编写单元测试,如:

func testinitializeHomeData() {
    let successExpectation = expectation(description: "")

    sut.initializeHomeData {
        successExpectation.fulfill()
    }

    waitForExpectations(timeout: 1.0,handler: nil)

    // Validation goes here
}

func testinitializeAnythingElse() {
    let successExpectation = expectation(description: "")

    sut.initializeAnythingElse {
        successExpectation.fulfill()
    }

    waitForExpectations(timeout: 1.0,handler: nil)

    // Validation goes here
}

我的问题是,如何测试reset()?我应该在testReset()中调用它们,如:

func testReset() {
    testinitializeHomeData()
    testinitializeAnythingElse()
}

但我认为这不是适当的实施.

解决方法

你是对的.要测试重置,您需要调用reset,而不是内部方法.

话虽这么说,重置目前的编写方式使其不可测试.您能够如此轻松地测试其他独立方法的原因是因为回调参数都接受了.

我建议你重写重置以允许两个可选的回调,如下所示:

typealias Callback = () -> ()

func reset(
    homeDataCallback: @escaping Callback? = nil,anythingElseCallback: @escaping Callback? = nil) {
    initializeAnythingElse() {
       anythingElseCallback?()
    }
    initializeHomeData() {
       homeDataCallback?()
    }
}

请注意,此更改允许您在异步时通知这两个内部调用是否完成.

现在,您的测试方法需要在编写时考虑某种同步原语,因为从逻辑上讲,只有当主数据和其他任何内容都完成并且调用了它们的回调时,才能完成重置.

有很多方法可以实现这一点,但我将向您展示一种信号量方法

func testReset() {

    let expectation = expectation(description: "reset() completes within some duration")

    // some mechanism to synchronize concurrent tasks
    // I am using a semaphore
    let s = dispatchSemaphore(value: 0)

    let homeCallback: Callback =  {
        s.signal() // signals the completion of home data init
    }

    let anythingElseCallback: Callback = {
        s.signal() // signals the completions of anything else setup
    }

    // call your reset method as part of the test
    reset(homeDataCallback: homeCallback,anythingElseCallback: anythingElseCallback)

    // we kNow we need to wait for two things to complete
    // init home data and anything else,so do that
    s.wait()
    s.wait()

    // at this step,reset's internal async methods
    // have completed so we can Now
    // fulfill the expectation
    expectation.fulfill()

}

请注意,所有这些更改都是纯粹允许您测试重置调用所必需的.函数签名允许您在现有代码中将reset()写为current,因为它具有可选参数,认值都设置为nil.

原文地址:https://www.jb51.cc/iOS/327744.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐