Как я могу пройти этот тест после представления Обещания классу?
У меня есть приложение, построенное с использованием шаблона MVP-C.
В моем HomeFlowCoordinator
Я называю начало, и это вызывает showHomeScene
метод, который устанавливает стек навигации с правильным контроллером представления.
Это выглядело так
protocol HomeFlowCoordinatorDelegate: class { }
class HomeFlowCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
let navigationController: UINavigationController
weak var delegate: HomeFlowCoordinatorDelegate?
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
showHomeScene()
}
private func showHomeScene() {
navigationController.setViewControllers([HomeConfigurator().configuredViewController(delegate: self)], animated: false)
}
}
extension HomeFlowCoordinator: HomeSceneDelegate { }
Я принял решение ввести асинхронный вызов для моей службы CompanyService, чтобы я мог получить некоторые удаленные ресурсы, необходимые до отображения представления, но после того, как пользователь вошел в систему.
Как я использую PromiseKit
Внедрение моего сервиса изменило вид координатора
protocol HomeFlowCoordinatorDelegate: class { }
class HomeFlowCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
let navigationController: UINavigationController
weak var delegate: HomeFlowCoordinatorDelegate?
private lazy var companyService = Dependencies.companyService.inject()
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
showHomeScene()
}
private func showHomeScene() {
companyService.fetch()
.done(on: DispatchQueue.main) { company in
BrandingProvider.shared.configure(branding: company.branding)
}.ensure {
self.navigationController.setViewControllers([HomeConfigurator().configuredViewController(delegate: self)], animated: false)
}.catch { err in
print(err)
}
}
}
extension HomeFlowCoordinator: HomeSceneDelegate { }
extension HomeFlowCoordinator {
struct Dependencies {
static let companyService = Injection<CompanyServiceProtocol>(CompanyService())
}
}
Функционально это работает, однако у меня есть 2 теста для моего координатора, которые сейчас не проходят.
Первоначально мой тестовый класс выглядел так
class HomeFlowCoordinatorTests: XCTestCase {
var sut: HomeFlowCoordinator!
override func setUp() {
super.setUp()
sut = HomeFlowCoordinator(navigationController: UINavigationController())
}
override func tearDown() {
super.tearDown()
sut = nil
}
func test_Start_NavigationControllerIsNotNil() {
sut.start()
XCTAssertFalse(sut.navigationController.viewControllers.isEmpty)
}
func test_ShowHomeScene_HomeSceneIsCorrectClass() {
sut.start()
XCTAssertTrue(sut.navigationController.visibleViewController is HomeViewController)
}
}
extension HomeFlowCoordinatorTests {
class MockHomeFlowCoordinatorDelegate: HomeFlowCoordinatorDelegate { }
}
Я попытался провести рефакторинг тестов следующим образом, но этот тест все еще не удался
func test_Start_NavigationControllerIsSetWhenCompanyThrows() {
let companyExpectation = expectation(description: "company")
class MockCompanyService: CompanyService {
var companyExpectation: XCTestExpectation!
override func fetch() -> Promise<Company> {
return Promise { seal in
let error = NSError(domain: "", code: 1, userInfo: nil)
companyExpectation.fulfill()
seal.reject(error)
}
}
}
let companyService = MockCompanyService()
HomeFlowCoordinator.Dependencies.companyService.overrideOnce = { companyService }
let sut = HomeFlowCoordinator(navigationController: UINavigationController())
companyService.companyExpectation = companyExpectation
sut.start()
waitForExpectations(timeout: 1) { _ in
XCTAssertFalse(sut.navigationController.viewControllers.isEmpty)
}
}
Я предположил, что, высмеивая сервис моей компании и оправдывая ожидания, ensure
Блок моего обещания должен сработать, и испытание должно пройти.