- RxBlocking does not work with Variable and PublishSubject, see https://github.com/ReactiveX/RxSwift/blob/0b66f666ba6955a51cba1ad530311b030fa4db9c/Tests/RxSwiftTests/Observable%2BSubscriptionTest.swift#L165
Use homemade Recorder
class Recorder<T> {
var items = [T]()
let bag = DisposeBag()
func on(arraySubject: PublishSubject<[T]>) {
arraySubject.subscribe(onNext: { value in
self.items = value
}).disposed(by: bag)
}
func on(valueSubject: PublishSubject<T>) {
valueSubject.subscribe(onNext: { value in
self.items.append(value)
}).disposed(by: bag)
}
}
Then test
final class BookViewModelTests: XCTestCase {
func testBooks() throws {
let expectation = self.expectation(description: #function)
let recorder = Recorder<Book>()
let viewModel = BookViewModel(bookClient: MockBookClient())
recorder.on(arraySubject: viewModel.books)
viewModel.load()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5, execute: {
expectation.fulfill()
})
wait(for: [expectation], timeout: 2)
XCTAssertEqual(recorder.items.count, 3)
}
}
Need to use great timeout
value as DispatchQueue
is not guaranteed to be precise, a block needs to wait for the queue to be empty before it can be executed
Make expectation
less cumbersome
extension XCTestCase {
func waitOrFail(timeout: TimeInterval) {
let expectation = self.expectation(description: #function)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + timeout, execute: {
expectation.fulfill()
})
wait(for: [expectation], timeout: timeout + 2)
}
}
❤️ Support my apps ❤️
- Push Hero - pure Swift native macOS application to test push notifications
- PastePal - Pasteboard, note and shortcut manager
- Quick Check - smart todo manager
- Alias - App and file shortcut manager
- My other apps
❤️❤️😇😍🤘❤️❤️
Top comments (0)