【问题标题】:RxJava 2: BehaviorSubject and Observable.combineLatest issuesRxJava 2:BehaviorSubject 和 Observable.combineLatest 问题
【发布时间】:2018-06-16 20:13:39
【问题描述】:

我在组合 BehaviorSubjectObservable.combineLatest 时遇到了一些问题。我能够在(较小的)测试中重现它。这是一个当前失败的测试:

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;
    }
}

(如果您用“COMMENT OUT THIS LINE”注释掉这两行,并将最后的3 替换为2,则测试成功。)

为什么这个测试失败了?我看不出代码有什么问题。

【问题讨论】:

    标签: java android unit-testing rx-java rx-java2


    【解决方案1】:

    它失败是因为你忘记了mainSubject.flatMap 仍然有第一个intSource 处于活动状态,因此intSource.onNext(1) 将首先触发combineLatest 序列。然后testObserver.assertValueAt(2) 将是List 中的单个值。 assertValueAt(3) 将包含 1, 2 而整个序列有 4 个项目。

    【讨论】:

    • 为什么mainSubject.flatMap 仍然是第一个intSource,因为我用newValue“替换”了intSource?测试反映了我希望看到的内容,因此我需要更改代码以反映测试的结果。
    • flatMap 合并源直到它们全部完成。 switchMap 是“替换”旧流程。
    • 非常感谢!这解决了它。您的建议很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多