Swift 如何断言使用最新文本输入的可观察对象的输出

Swift 如何断言使用最新文本输入的可观察对象的输出,swift,reactive-programming,xctest,rx-swift,rxtest,Swift,Reactive Programming,Xctest,Rx Swift,Rxtest,我的视图模型上有一个属性: let isValid:驱动程序 让凭据:驱动程序 ...... 凭据=.CombineTest(bindings.username,bindings.password,resultSelector:{(用户名,密码)->(字符串,字符串)在(用户名,密码)} isValid=credentials.map{username.count>0&&password.count>7} 我想断言,当设置有效输入时,正确的状态设置为isValid 我的测试在下面通过了,但是这

我的视图模型上有一个属性:

let isValid:驱动程序
让凭据:驱动程序
......
凭据=.CombineTest(bindings.username,bindings.password,resultSelector:{(用户名,密码)->(字符串,字符串)在(用户名,密码)}
isValid=credentials.map{username.count>0&&password.count>7}
我想断言,当设置有效输入时,正确的状态设置为
isValid

我的测试在下面通过了,但是这并不是测试这个场景的正确方法

理想情况下,我希望从字符串开始,即
,然后像键入值一样传入值,这样我就可以断言默认状态已设置,然后更改

我还发现以下几行:

   .do(onNext: { state in
            if state {
                exp.fulfill()
            }
        })
有点“哈奇”

func测试\u有效\u状态\u在\u输入\u正确\u长度()时发生变化{
让用户名:Driver=.of(“某个用户名”)
let password:Driver=.of(“某些用户密码”)
让bindings=LoginViewModel.bindings(用户名:用户名,密码:密码,loginTap:.empty(),doneTap:.empty())
让sut=LoginViewModel(依赖项:“”,绑定:绑定)
let scheduler=TestScheduler(初始时钟:0)
让observer=scheduler.createObserver(Bool.self)
let exp=期望值(描述:“isValid事件”)
sut.isValid
.asObservable()
.do(onNext:{在
如果状态{
exp.fulfill()
}
})
.订阅(观察员)
.处置(由:处置人)
scheduler.start()
WaitForExpections(超时:0.5){中出现错误
xctasertnil(错误)
xctasertequal(observer.events.count,1)
xctasertrue(observer.events[0].value.element!)//swiftlint:disable:this force\u unwrapping
}
}

您需要使用TestObservables来执行您想要的测试,并且您不需要期望对象,因为此测试将在没有任何线程问题的情况下完成

    func test_is_valid_state_changes_when_inputs_correct_length() {
        let scheduler = TestScheduler(initialClock: 0)

        let username = scheduler.createHotObservable([.next(0, ""), .next(10, "h")])
        let password = scheduler.createHotObservable([.next(0, ""), .next(30, "p"), .next(40, "passwor"), .next(50, "password")])

        let bindings = LoginViewModel.Bindings(
            username: username.asDriver(onErrorRecover: { _ in XCTFail(); return .empty() }),
            password: password.asDriver(onErrorRecover: { _ in XCTFail(); return .empty() }),
            loginTap: .empty(),
            doneTap: .empty()
        )
        let disposeBag = DisposeBag()
        let sut = LoginViewModel(dependency: "", bindings: bindings)

        let observer = scheduler.createObserver(Bool.self)

        sut.isValid
            .drive(observer)
            .disposed(by: disposeBag)

        scheduler.start()

        XCTAssertEqual(observer.events, [
            .next(0, false),
            .next(10, false),
            .next(30, false),
            .next(40, false),
            .next(50, true)
        ])

    }

如果您的观察对象/驱动程序是从测试调度器创建的,那么您不必等待预期。我使用的是
waitforexpections
,因为我只对状态为
true
@TeddyK感兴趣。您在问题中说,您感兴趣的是状态如何对输入中的更改做出反应。这不仅仅是“真实”。