swift - XCTest - 无法理解/实现单元测试中的期望(测试异步代码)

标签 swift macos cocoa xctest

(注意 - 我正在针对 macOS 进行开发,所以请...特定于 iOS 的建议对我没有帮助)

我正在尝试做的事情: 我有一个应用程序组件,它在后台线程上执行一个简短的任务,然后,如果满足某些条件,则在主线程上异步发送通知。

注意 - 我没有在我的应用代码中使用 NSNotification。我正在使用我自己的自定义通知机制。所以,任何与 NSNotification 相关的解决方案都不适合我。

我正在为上述应用程序组件编写单元测试,并且只是想检查该通知是否确实已发送。我的测试必须能够等待一秒钟左右,以便在执行断言之前给通知时间到达其订阅者/观察者。

我希望能够在我的测试中测试两种可能的情况:这两种情况都是正常情况。

  • 通知已发送。

  • 未发送通知。

在阅读了几个文档和代码示例后,我不明白如何按照预期实现这一目标。

我只想在测试中等待一秒钟。真的这么复杂吗?

  • sleep() 不起作用
  • DispatchQueue.main.asyncAfter(time) 不起作用
  • 计时器不起作用

这是需要测试的应用程序组件及其单元测试:

在下面的代码中,我该把expectation.fulfill()放在哪里???

class ComponentBeingTested {

    func methodBeingTested() {

        doSomeWork()
        if certainConditionsAreMet {
             DispatchQueue.main.async {sendOutNotification()}
        }
    }
}

...

class UnitTestForComponentBeingTested: XCTestCase {

    let objectBeingTested = ComponentBeingTested()

    func testMethodBeingTested() {

          let expectation = self.expectation(description: "Notification was sent")

          // Call the code being tested
          objectBeingTested.methodBeingTested()

          // How do I do this with expectations ??? Where does expectation.fulfill() go ?
          waitForOneSecond()

          XCTAssertTrue(notificationSent)      // Assume the value of notificationSent is available

    }
}

最佳答案

这是一种方法

func testMethodBeingTested() {

      // create expectation
      let expectation = self.expectation(description: "Notification was sent")

      // set expectation condition
      var notificationSent = false
      let observer = NotificationCenter.default
            .addObserver(forName: _Your_Notification_Name, object: nil, queue: nil) { _ in
            notificationSent = true
            expectation.fulfill()
        }

      // Call the code being tested
      objectBeingTested.methodBeingTested()

      // wait for expectation
      self.wait(for: [expectation], timeout: 5)

      XCTAssertTrue(notificationSent)
}

关于swift - XCTest - 无法理解/实现单元测试中的期望(测试异步代码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61734845/

相关文章:

macos - 如何更改 VoiceOver 对没有标题(仅图像)的 NSButton 读取的内容?

cocoa - 读取 Cocoa 中的音频输入电平峰值

ios - 查找两个对象之间更改的属性

ios - Google Cast 设备 DidComeOnline(设备 : GCKDevice!)从未被调用 #GoogleCastSDK

ios - 单击按钮展开表格 View 单元格

ios - CallKit 在 iOS 中处理多个调用(VOIP 和 GSM)问题

macos - 我无法让 Mercurial 在 Mac OS X Lion 上的 Apache 下运行

python - 在 Mac OS X 中设置 PocketSphinx

objective-c - 如何检测/观察第三方应用何时启动全屏进程?

iphone - cocoa - 连接 :didFailWithError error codes