我在测试合并时遇到困难。我正在跟踪:
哪些测试:
final class ViewModel {
@Published private(set) var tokens = [String]()
@Published var string = ""
private let tokenizer = Tokenizer()
init () {
$string
.flatMap(tokenizer.tokenize)
.replaceError(with: [])
.assign(to: &$tokens)
}
}
struct Tokenizer {
func tokenize(_ string: String) -> AnyPublisher<[String], Error> {
let strs = string.components(separatedBy: " ")
return Just(strs)
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
}
字符串
其中包括:
func testTokenizingMultipleStrings() throws {
let viewModel = ViewModel()
let tokenPublisher = viewModel.$tokens
.dropFirst()
.collect(2)
.first()
viewModel.string = "Hello @john"
viewModel.string = "Check out #swift"
let tokenArrays = try awaitPublisher(tokenPublisher)
XCTAssertEqual(tokenArrays.count, 2)
XCTAssertEqual(tokenArrays.first, ["Hello", "john"])
XCTAssertEqual(tokenArrays.last, ["Check out", "swift"])
}
型
下面是helper函数:
extension XCTestCase {
func awaitPublisher<T: Publisher>(
_ publisher: T,
timeout: TimeInterval = 10,
file: StaticString = #file,
line: UInt = #line
) throws -> T.Output {
var result: Result<T.Output, Error>?
let expectation = self.expectation(description: "Awaiting publisher")
let cancellable = publisher.sink(
receiveCompletion: { completion in
switch completion {
case .failure(let error):
result = .failure(error)
case .finished:
break
}
expectation.fulfill()
},
receiveValue: { value in
result = .success(value)
}
)
waitForExpectations(timeout: timeout)
cancellable.cancel()
let unwrappedResult = try XCTUnwrap(
result,
"Awaited publisher did not produce any output",
file: file,
line: line
)
return try unwrappedResult.get()
}
}
型
这里receiveValue
从未被调用,所以测试没有完成。我如何让这个测试通过?
3条答案
按热度按时间iqjalb3h1#
我遇到了同样的问题,最终意识到要想通过测试,我们需要在设置订阅和等待期望之间更新view-model。由于这两个过程目前都发生在
awaitPublisher
助手中,我给这个函数添加了一个闭包参数:字符串
注意闭包的确切位置--如果调用得太早或太晚,它都不会工作。
然后你可以在测试中像这样调用助手:
型
b4qexyjb2#
字符串
你的
tokenPublisher
不会做任何事情,直到你订阅它。在这段代码中,你创建了发布者,做了一些动作,* 如果 * 有人订阅了它,* 会 * 通过发布者推送值,然后你调用awaitPublisher
(订阅的东西)。你需要反转这些:型
zf9nrax13#
不幸的是,我没有发现上面的答案有帮助。后来,我发现了这个Swift Package,它优雅地解决了我们的痛点。这个作者保存我一天。
下面是我的测试函数示例。
字符串