TestScheduler
TestSchedulers 允許你控制 Observables 的時間和執行,而不必進行繁忙的等待,加入執行緒或任何作業系統時間。如果你想編寫可預測,一致且快速的單元測試,這非常重要。因為你正在操作時間,所以執行緒不再有機會,你的測試在較慢的機器上失敗,或者浪費執行時間忙於等待結果。
可以通過過載提供 TestSchedulers,該過載將排程程式用於任何 RxJava 操作。
TestScheduler testScheduler = new TestScheduler();
TestSubscriber<Integer> subscriber = TestSubscriber.create();
Observable.just(1,2,3)
.delay(10, TimeUnit.SECONDS, testScheduler)
.subscribe(subscriber);
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(11));
} catch (InterruptedException ignored) { }
subscriber.assertValues(1,2,3); // fails
testScheduler.advanceTimeBy(10, TimeUnit.SECONDS);
subscriber.assertValues(1,2,3); // success
TestScheduler 非常基礎。它只包含三種方法。
testScheduler.advanceTimeBy(amount, timeUnit);
testScheduler.advanceTimeTo(when, timeUnit);
testScheduler.triggerActions();
這使你可以在 TestScheduler 應該觸發將來某個時間的所有操作時進行操作。
在傳遞排程程式時,這不是 TestScheduler 的常用方法,因為它的效率低。將排程程式傳遞給類最終會提供大量額外程式碼以獲得很少的收益。相反,你可以掛鉤到 RxJava 的 Schedulers.io()
/ computation()
/ etc。這是通過 RxJava 的 Hooks 完成的。這使你可以定義從其中一個 Scheduler 方法呼叫返回的內容。
public final class TestSchedulers {
public static TestScheduler test() {
final TestScheduler testScheduler = new TestScheduler();
RxJavaHooks.reset();
RxJavaHooks.setOnComputationScheduler((scheduler) -> {
return testScheduler;
});
RxJavaHooks.setOnIOScheduler((scheduler) -> {
return testScheduler;
});
RxJavaHooks.setOnNewThreadScheduler((scheduler) -> {
return testScheduler;
});
return testScheduler;
}
}
此類允許使用者獲取將連線到排程程式的所有呼叫的測試排程程式。單元測試只需要在其設定中獲得此排程程式。強烈建議在設定中查詢它而不是任何普通的舊欄位,因為你的 TestScheduler 可能會在你提前時間時嘗試從另一個單元測試中觸發操作。現在我們的例子變成了
TestScheduler testScheduler = new TestScheduler();
TestSubscriber<Integer> subscriber = TestSubscriber.create();
Observable.just(1,2,3)
.delay(10, TimeUnit.SECONDS, testScheduler)
.subscribe(subscriber);
testScheduler.advanceTimeBy(9, TimeUnit.SECONDS);
subscriber.assertValues(); // success (delay hasn't finished)
testScheduler.advanceTimeBy(10, TimeUnit.SECONDS);
subscriber.assertValues(1,2,3); // success (delay has finished)
這就是你如何有效地從單元測試中刪除系統時鐘(至少就 RxJava 而言😆)