В моем тесте я хочу убедиться, что метод презентатора вызывается при запуске viewDidLoad интерактора. Я использую макет презентатора и проверяю, вызываются ли ожидаемые методы. Однако методы, вызывающие презентатор, необходимо ожидать, поскольку они запускаются с использованием @MainActor, и я не знаю, как ожидать их в своих тестах.
Вот упрощенная версия моего интерактора:
Код: Выделить всё
protocol MyInteractorProtocol {
func viewDidLoad()
}
class MyInteractor: MyInteractorProtocol {
private var presenter: MyPresenterProtocol
init(presenter: MyPresenterProtocol) {
self.presenter = presenter
}
func viewDidLoad() {
Task {
await fetchData()
}
}
private func fetchData() async {
// Some data fetching here
await updateUI()
}
@MainActor
private func updateUI() {
presenter.presentData()
}
}
Код: Выделить всё
import XCTest
final class MyInteractorTests: XCTestCase {
func testViewDidLoadCallsPresenterUsingSleep() async throws {
let mockPresenter = MockPresenter()
let interactor = MyInteractor(presenter: mockPresenter)
interactor.viewDidLoad()
// I'm currently using sleep to wait for the async task to finish
try await Task.sleep(nanoseconds: 1_000_000_000) // 1 second
XCTAssertTrue(mockPresenter.presentDataCalled)
}
func testViewDidLoadCallsPresenterUsingExpectation() {
let mockPresenter = MockPresenter()
let interactor = MyInteractor(presenter: mockPresenter)
let expectation = expectation(description: "Presenter should call presentData")
Task {
interactor.viewDidLoad()
expectation.fulfill()
}
wait(for: [expectation])
XCTAssertTrue(mockPresenter.presentDataCalled)
}
}
Вопрос: Как правильно тестировать асинхронные задачи в Swift XCTest, не полагаясь на на Task.sleep() или произвольные задержки? В идеале я хочу, чтобы тест ждал завершения задачи, прежде чем выполнять утверждения, но без жестко запрограммированных продолжительностей сна или хаков, чтобы заставить его работать. Есть какие-нибудь предложения по улучшению схемы тестирования в этом случае?
Подробнее здесь: https://stackoverflow.com/questions/789 ... -in-xctest