[英]RxJava Observable timeout before first element
I have device that send me ping, and I use observable for this.我有向我发送 ping 的设备,为此我使用了 observable。 But before first ping we start connection and it takes some time.但在第一次 ping 之前,我们开始连接,这需要一些时间。 Therefore I want first ping have 10 sec timeout.因此我希望第一次 ping 有 10 秒的超时。 I make it this way:我这样做:
public Observable<Ping> getPing() {
ConnectableObservable<Ping> observable = device.connectToDevice().publish();
Observable<Ping> firstWithTimeout = observable.take(1).timeout(10, TimeUnit.SECONDS);
Observable<Ping> fromSecondWithoutTimeout = observable.skip(1);
Observable<Ping> mergedObservable = firstWithTimeout.mergeWith(fromSecondWithoutTimeout)
.doOnDispose(() -> disconnect(bluetoothDevice))
.doOnError(error -> disconnect(bluetoothDevice));
observable.connect();
return mergedObservable;
}
For test I use为了测试我使用
Subject<Ping> observable = PublishSubject.create();
when(device.connect()).thenReturn(observable);
TestObserver<Ping> testSubscriber = TestObserver.create();
getPing.subscribe(testSubscriber);
observable.onNext(new Ping());
testSubscriber.assertValueCount(1);
This test will fail, because TimeoutException, in spite I send ping instantly.尽管我立即发送了 ping,但该测试将失败,因为 TimeoutException。
There is an overloaded timeout
operator that will perfectly fit here:有一个重载的timeout
操作符非常适合这里:
timeout(ObservableSource<U> firstTimeoutIndicator, Function<? super T, ? extends ObservableSource<V>> itemTimeoutIndicator)
Assuming that your observable reference is testObserable
you simply do the:假设您的可观察引用是testObserable
您只需执行以下操作:
testObservable.timeout(
Observable.timer(5L, TimeUnit.SECONDS), // here you set first item timeout
ignored -> Observable.never() // for other elements there is no time function
)
Please have a look at this setup:请看一下这个设置:
JUnit5 / RxJava2 JUnit5 / RxJava2
I think you error a incorrect configuration of the mock我认为你错误的模拟配置不正确
when(device.connect()).thenReturn(observable);当(device.connect()).thenReturn(observable);
Please have a look at my implementation.请看一下我的实现。 There is no need to use publish / connect when you are createing a new observable with every method-invocation.当您为每个方法调用创建新的 observable 时,无需使用发布/连接。 Use autoConnect in device for method-impl connectToDevice()在设备中使用 autoConnect for method-impl connectToDevice()
Device device;
@BeforeEach
void setUp() {
device = mock(Device.class);
}
@Test
void name() throws Exception {
Subject<Ping> observable = PublishSubject.create();
when(device.connectToDevice()).thenReturn(observable);
TestObserver<Ping> test = getPing(Schedulers.computation()).test();
observable.onNext(new Ping());
test.assertValueCount(1);
}
@Test
void name2() throws Exception {
Subject<Ping> observable = PublishSubject.create();
when(device.connectToDevice()).thenReturn(observable);
TestScheduler testScheduler = new TestScheduler();
TestObserver<Ping> test = getPing(testScheduler).test();
testScheduler.advanceTimeBy(20, TimeUnit.SECONDS);
observable.onNext(new Ping());
test.assertError(TimeoutException.class);
}
private Observable<Ping> getPing(Scheduler scheduler) {
return device
.connectToDevice()
.take(1)
.timeout(10, TimeUnit.SECONDS, scheduler)
.doOnDispose(() -> disconnect())
.doOnError(error -> disconnect());
}
private void disconnect() {}
interface Device {
Observable<Ping> connectToDevice();
}
class Ping {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.