2014-11-02 27 views
10

Tôi nên sử dụng số TestScheduler của RxJava như thế nào? Tôi đến từ một nền .NET nhưng TestScheduler trong RxJava dường như không hoạt động theo cách tương tự như trình lên lịch kiểm tra trong .NET rx.Cách sử dụng TestScheduler trong RxJava

Đây là mẫu mã mà tôi muốn kiểm tra

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() 

Tôi đã thử:

subscribeOn(testScheduler) 
testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); 
testScheduler.triggerActions(); 

không có may mắn.

+0

Bạn không chuyển 'TestScheduler' vào' Observable.Interval'. Đó cũng là một vấn đề trong .NET. –

Trả lời

20

Tôi đã tạo một ví dụ nhỏ về cách sử dụng TestScheduler. Tôi nghĩ rằng nó rất giống với việc thực hiện NET

@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 Theo mã của bạn: bạn nên vượt qua lịch trình đến hoạt động Observable.interval, vì đây là những gì bạn muốn kiểm soát:

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); 
+1

Vâng, điều này là tuyệt vời, nhưng làm thế nào về việc thử nghiệm một 'thực/mảnh mã, chúng ta hãy ở lại bạn có một phương pháp với một thuê bao quan sát thực hiện một số gọi lại onComplete và một số callback onError khác. Tôi đã tiêm lịch trình kiểm tra trong 'subscribeOn' nhưng không có may mắn từ đó. – Calin

+1

Bạn có thể đăng một số mã để nêu chi tiết vấn đề của mình không? – dwursteisen

+0

đã thêm mã mẫu – Calin

7

bạn có một số lớp:

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() 
    } 
} 

Tra cứu [Observable.interval][1] trong tài liệu và bạn sẽ thấy nó hoạt động trên trình lập lịch tính toán, vì vậy hãy ghi đè lên điều đó trong thử nghiệm của chúng tôi.

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

Giải pháp này là một cải tiến cho câu trả lời được chấp nhận vì chất lượng, tính toàn vẹn và đơn giản của mã sản xuất được duy trì.

+1

Cảm ơn! Tôi đang sử dụng 'throttleFirst' và các bài kiểm tra của tôi không thành công vì nó không nâng cao thời gian như TestScheduler của tôi. –

Các vấn đề liên quan