How to use TestScheduler in RxJava

前端 未结 2 614
臣服心动
臣服心动 2020-12-18 19:43

How should I use RxJava\'s TestScheduler? I come from a .NET background but the TestScheduler in RxJava does not seem to work the same way as the t

相关标签:
2条回答
  • 2020-12-18 20:19

    I made a little example of how to use a TestScheduler. I think it's very similar to the .NET implementation

    @Test
    public void should_test_the_test_schedulers() {
        TestScheduler scheduler = new TestScheduler();
        final List<Long> result = new ArrayList<>();
        Observable.interval(1, TimeUnit.SECONDS, scheduler)
            .take(5)
            .subscribe(result::add);
        assertTrue(result.isEmpty());
        scheduler.advanceTimeBy(2, TimeUnit.SECONDS);
        assertEquals(2, result.size());
        scheduler.advanceTimeBy(10, TimeUnit.SECONDS);
        assertEquals(5, result.size());
    }
    

    https://github.com/bric3/demo-rxjava-humantalk/blob/master/src/test/java/demo/humantalk/rxjava/SchedulersTest.java

    EDIT According to your code : you should pass the scheduler to the Observable.interval operation, as this is what you want to control :

        TestScheduler scheduler = new TestScheduler();
    
        Observable<Long> tick = Observable.interval(1, TimeUnit.SECONDS, scheduler);
        Subscription toBeTested = Observable.from(Arrays.asList(1, 2, 3, 4, 5))
                .buffer(3)
                .zipWith(tick, (i, t) -> i)
                .subscribe(System.out::println);
    
        scheduler.advanceTimeBy(2, TimeUnit.SECONDS);
    
    0 讨论(0)
  • 2020-12-18 20:29

    you have some class:

    public class SomeClass {
      public void someMethod() {
        Observable<Long> tick = Observable.interval(1, TimeUnit.SECONDS);
        contactsRepository.find(index)
          .buffer(MAX_CONTACTS_FETCH)
          .zipWith(tick, new Func2<List<ContactDto>, Long, List<ContactDto>>() {
            @Override
            public List<ContactDto> call(List<ContactDto> contactList, Long aLong) {
              return contactList;
            }
          }).subscribe()
      }
    }
    

    Look up [Observable.interval][1] in the docs and you will see it operates on the computation scheduler, so lets override that in our test.

    public class SomeClassTest {
      private TestScheduler testScheduler;
    
      @Before
      public void before() {
        testScheduler = new TestScheduler();
        // set calls to Schedulers.computation() to use our test scheduler
        RxJavaPlugins.setComputationSchedulerHandler(ignore -> testScheduler);
      }
    
      @After
      public void after() {
        // reset it
        RxJavaPlugins.setComputationSchedulerHandler(null);
      }
    
      @Test
      public void test() {
        SomeClass someInstance = new SomeClass();
        someInstance.someMethod();
    
        // advance time manually
        testScheduler.advanceBy(1, TimeUnit.SECONDS);
      }
    

    This solution is an improvement to the accepted answer as the quality, integrity and simplicity of the production code is maintained.

    0 讨论(0)
提交回复
热议问题