我如何 return 此测试中可观察值的下一个值?
How can I return the next value of an observable in this test?
我正在开发一个基于以下应用程序的项目:
我正在尝试围绕 BaseCoordinator
class 编写单元测试。
我想断言此方法在 class
private func free<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = nil
}
实际上确实从 childCoordinators
字典中释放了协调器。
不过我不确定我该怎么做。我以为我可以简单地创建一个模拟协调器并使用 start
方法 return 东西,但我相信我做错了
我的测试
func test_releases_coordinator_from_child_coordinator_dict() {
class MockCoordinator: BaseCoordinator<Void> {
override func start() -> Observable<Void> {
return .empty()
}
}
let mockCoordinator = MockCoordinator()
let sut = BaseCoordinator<Void>()
sut.coordinate(to: mockCoordinator).subscribe().disposed(by: disposeBag)
XCTAssertEqual(sut.childCoordinators.count, 0)
}
我的基地协调员
import RxSwift
/// Base abstract coordinator generic over the return type of the `start` method.
class BaseCoordinator<ResultType>: CoordinatorType {
/// Typealias which allows to access a ResultType of the Coordainator by `CoordinatorName.CoordinationResult`.
typealias CoordinationResult = ResultType
/// Utility `DisposeBag` used by the subclasses.
let disposeBag = DisposeBag()
/// Unique identifier.
internal let identifier = UUID()
/// Dictionary of the child coordinators. Every child coordinator should be added
/// to that dictionary in order to keep it in memory.
/// Key is an `identifier` of the child coordinator and value is the coordinator itself.
/// Value type is `Any` because Swift doesn't allow to store generic types in the array.
private(set) var childCoordinators = [UUID: Any]()
/// Stores coordinator to the `childCoordinators` dictionary.
///
/// - Parameter coordinator: Child coordinator to store.
private func store<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = coordinator
}
/// Release coordinator from the `childCoordinators` dictionary.
///
/// - Parameter coordinator: Coordinator to release.
private func free<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = nil
}
/// 1. Stores coordinator in a dictionary of child coordinators.
/// 2. Calls method `start()` on that coordinator.
/// 3. On the `onNext:` of returning observable of method `start()` removes coordinator from the dictionary.
///
/// - Parameter coordinator: Coordinator to start.
/// - Returns: Result of `start()` method.
func coordinate<T: CoordinatorType, U>(to coordinator: T) -> Observable<U> where U == T.CoordinationResult {
store(coordinator: coordinator)
return coordinator.start()
.do(onNext: { [weak self] _ in self?.free(coordinator: coordinator) })
}
/// Starts job of the coordinator.
///
/// - Returns: Result of coordinator job.
func start() -> Observable<ResultType> {
fatalError("Start method should be implemented.")
}
}
您不能使用 .empty
作为您在 MockCoordinator
中的 return 类型。
empty
创建一个 Observable,它不发射任何项目,但不会失败。
您也应该更新模拟以在订阅后发出一个值,例如:
class MockCoordinator: BaseCoordinator<Bool> {
override func start() -> Observable<Bool> {
return .of(true)
}
}
这应该 调用以释放您的协调器。
我正在开发一个基于以下应用程序的项目:
我正在尝试围绕 BaseCoordinator
class 编写单元测试。
我想断言此方法在 class
private func free<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = nil
}
实际上确实从 childCoordinators
字典中释放了协调器。
不过我不确定我该怎么做。我以为我可以简单地创建一个模拟协调器并使用 start
方法 return 东西,但我相信我做错了
我的测试
func test_releases_coordinator_from_child_coordinator_dict() {
class MockCoordinator: BaseCoordinator<Void> {
override func start() -> Observable<Void> {
return .empty()
}
}
let mockCoordinator = MockCoordinator()
let sut = BaseCoordinator<Void>()
sut.coordinate(to: mockCoordinator).subscribe().disposed(by: disposeBag)
XCTAssertEqual(sut.childCoordinators.count, 0)
}
我的基地协调员
import RxSwift
/// Base abstract coordinator generic over the return type of the `start` method.
class BaseCoordinator<ResultType>: CoordinatorType {
/// Typealias which allows to access a ResultType of the Coordainator by `CoordinatorName.CoordinationResult`.
typealias CoordinationResult = ResultType
/// Utility `DisposeBag` used by the subclasses.
let disposeBag = DisposeBag()
/// Unique identifier.
internal let identifier = UUID()
/// Dictionary of the child coordinators. Every child coordinator should be added
/// to that dictionary in order to keep it in memory.
/// Key is an `identifier` of the child coordinator and value is the coordinator itself.
/// Value type is `Any` because Swift doesn't allow to store generic types in the array.
private(set) var childCoordinators = [UUID: Any]()
/// Stores coordinator to the `childCoordinators` dictionary.
///
/// - Parameter coordinator: Child coordinator to store.
private func store<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = coordinator
}
/// Release coordinator from the `childCoordinators` dictionary.
///
/// - Parameter coordinator: Coordinator to release.
private func free<T: CoordinatorType>(coordinator: T) {
childCoordinators[coordinator.identifier] = nil
}
/// 1. Stores coordinator in a dictionary of child coordinators.
/// 2. Calls method `start()` on that coordinator.
/// 3. On the `onNext:` of returning observable of method `start()` removes coordinator from the dictionary.
///
/// - Parameter coordinator: Coordinator to start.
/// - Returns: Result of `start()` method.
func coordinate<T: CoordinatorType, U>(to coordinator: T) -> Observable<U> where U == T.CoordinationResult {
store(coordinator: coordinator)
return coordinator.start()
.do(onNext: { [weak self] _ in self?.free(coordinator: coordinator) })
}
/// Starts job of the coordinator.
///
/// - Returns: Result of coordinator job.
func start() -> Observable<ResultType> {
fatalError("Start method should be implemented.")
}
}
您不能使用 .empty
作为您在 MockCoordinator
中的 return 类型。
empty
创建一个 Observable,它不发射任何项目,但不会失败。
您也应该更新模拟以在订阅后发出一个值,例如:
class MockCoordinator: BaseCoordinator<Bool> {
override func start() -> Observable<Bool> {
return .of(true)
}
}
这应该 调用以释放您的协调器。