Closed yozh1que closed 4 years ago
Why do you need an MVI way to test the logic before the map? You should just be able to test the logic to see if you are getting the output you are expecting. Your Wish shouldn't be doing any logic so as long as the logic to give it what it wants works you can safely assume you have what you need.
However, if you want you can simulate text changes with Observable.just
and ensure that the logic works as intended (but again, it seems that the logic is what you are truly trying to test here).
Use a TestSubscriber
to subscribe to the Observable
and check that your SomeWish
is equal to the one that is created.
For instance:
val expectedWish = SomeWish(result = true)
val testSubscriber = TestSubscriber<SomeWish>()
Observable.combineLatest(
Observable.just("1", "2", "3"),
Observable.just("1", "2", "3"),
BiFunction<CharSequence, CharSequence, Boolean>() { v1, v2 ->
v1.length == v2.length && v1.length == limit
}
)
// ... do logic
.map { result -> SomeWish(result) }
.subscribe(testSubscriber)
testSubscriber.assertValues(expectedWish);
Hey, usually we connect those things through the binder e.g.
val from = Observable.combineLatest(
Observable.just("1", "2", "3"),
Observable.just("1", "2", "3"),
BiFunction<CharSequence, CharSequence, Boolean>() { v1, v2 ->
v1.length == v2.length && v1.length == limit
}
)
binder.bind(from to feature using SomeLogic)
SomeLogic
in the example above can be either:
(A) -> B?
ObservableSource<A> -> ObservableSource<B>
(Connector
)These functions can be tested separately, e.g. you can provide Observable<A>
to connector and check that Observable<B>
is emitting something matching your expectations.
Note that you can do it without binder as well, just extracting logic between combineLatest
and map
to a separate function/class.
Thanks for your suggestions, guys. I ended up relaying events to the actor and handling ui logic there. I also had to expand state objects to include ui-related fields (like "typed password at full length, error should be displayed") which, I now think, is not a bad thing - it makes view "dumb", isolates logic from the framework and empowers tdd.
Could you provide a view on how to implement tests that cover interactions with UI. In MVVM it was solely done inside ViewModel but with MVI I'm not sure where it belongs.
Say, inside a fragment we need to combine values from several edittexts and send a wish based on some criteria:
Is there an mvi way to test the logic before the
map
?I know there's a concept of actor middleware that deals with async requests and other backend logic - do you think it should also cover ui-related checks? Wouldn't it bloat State?
Thanks!