Reputation: 12571
I'm having some issues with combining both a BehaviorSubject
and Observable.combineLatest
. I was able to reproduce it in a (smaller) test. Here is a test which is currently failing:
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.observers.TestObserver;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.Subject;
import static java.util.Collections.singletonList;
public class MyTest {
@Test
public void test() {
Subject<Integer> intSource = BehaviorSubject.createDefault(1);
Subject<List<Observable<Integer>>> mainSubject =
BehaviorSubject.createDefault(singletonList(intSource));
TestObserver<List<Integer>> testObserver =
mainSubject.flatMap(observables ->
Observable.combineLatest(observables, this::castObjectsToInts)
)
.test();
List<Observable<Integer>> newValue = new ArrayList<>();
newValue.add(intSource); // same value as before
newValue.add(Observable.just(2)); // add another value to this list.
mainSubject.onNext(newValue);
// intSource was already '1', but this is just to 'update' it.
intSource.onNext(1); // COMMENT OUT THIS LINE
testObserver.assertValueAt(0, singletonList(1));
testObserver.assertValueAt(1, Arrays.asList(1, 2));
testObserver.assertValueAt(2, Arrays.asList(1, 2)); // COMMENT OUT THIS LINE
testObserver.assertValueCount(3); // REPLACE 3 WITH 2
}
private List<Integer> castObjectsToInts(Object[] objects) {
List<Integer> ints = new ArrayList<>(objects.length);
for (Object object : objects) {
ints.add((Integer) object);
}
return ints;
}
}
(If you comment out both lines with "COMMENT OUT THIS LINE", and replace the last 3
with a 2
, the test succeeds.)
Why is this test failing? I don't see anything wrong with the code.
Upvotes: 1
Views: 2513
Reputation: 70007
It fails because you forgot that the mainSubject.flatMap
still has the first intSource
active, thus the intSource.onNext(1)
will first trigger that combineLatest
sequence. The testObserver.assertValueAt(2)
then will be that single value in a List
. assertValueAt(3)
will contain the 1, 2
instead and the whole sequence has 4 items.
Upvotes: 2