-1

我正在为使用组合框架的代码编写单元测试

我有一个异步操作,所以我expectation(descrption:)用来等待异步操作

这是我的代码示例

class MyViewModel {
  private var someOtherSubject: CurrentValueSubject<...>(...)
  var someOtherStream: ... { 
    return someOtherSubject.eraseToAnyPublisher()
  }
  
  init(...) { 
    .
    .
    bind()
  }

  private func bind() { 
    . 
    .
    .
    someOfMySubject
      .flatMap { someAsyncOperation }
      .sink { [weak self] ... in 
         self?.someOtherSubject.send(value2)
      }
      .store(..)
  }

  .
  .

  func handleSomeUserAction() {
    self.someOtherSubject.send(value1)
    self.someOfMySubject.send(someEvent)
  }
}

我正在尝试检查调用someOtherStream时发出的值handleSomeUserAction

所以我写了这样的测试代码

func test_handleSomeUserAction() { 
  // given 
  let expectation = expectation(description: "...")
  var result: ValueType?

  // when 
  sut.someOtherStream
    .dropFirst() // drop CurretValueSubject's default value
    .sink { 
      result = $0
      expectation.fulfill()
    }
    .store(...)
  sut.handleSomeUserAction()

  // then
  wait(for: [expectation], timeout: 1.0)
  let unwrapped = try XCTUnwrap(result)
  XCTAssertEqual(unwrapped, value1)
}

我知道expectedFulfillmentCount是 1 因为它的默认值是 1

但测试失败,Xcode 向我显示此消息

API 违规 - 多次调用 -[XCTestExpectation 完成]

所以我尝试调试,尽管是 1 ,但我发现expectation.fulfill()调用了两次expectedFulfillmentCount

结果value2不是value1我所期望的

为什么会这样?我认为异步操作(flatMap {...})完成得太快并被fulfill调用了两次。

我尝试了延迟模拟方法,但我认为这不是正确的解决方案

4

1 回答 1

1

你的代码有点奇怪。但看起来您正在向 someOtherStream. 所以预计sink会被调用两次。

于 2021-10-20T08:56:21.450 回答