/** * The error from the user provided Observable is handled by the subscribe try/catch because this * is synchronous * * <p>Result: Passes */ @Test public void testCustomObservableWithErrorInObservableSynchronous() { final AtomicInteger count = new AtomicInteger(); final AtomicReference<Throwable> error = new AtomicReference<>(); // FIXME custom built??? Observable.just("1", "2") .concatWith(Observable.error(() -> new NumberFormatException())) .subscribe( new Observer<String>() { @Override public void onComplete() { System.out.println("completed"); } @Override public void onError(Throwable e) { error.set(e); System.out.println("error"); e.printStackTrace(); } @Override public void onNext(String v) { System.out.println(v); count.incrementAndGet(); } }); assertEquals(2, count.get()); assertNotNull(error.get()); if (!(error.get() instanceof NumberFormatException)) { fail("It should be a NumberFormatException"); } }
@Test public void testAlreadyUnsubscribedInterleavesWithClient() { ReplaySubject<Integer> source = ReplaySubject.create(); Subscriber<Integer> done = Subscribers.empty(); done.unsubscribe(); @SuppressWarnings("unchecked") Observer<Integer> o = mock(Observer.class); InOrder inOrder = inOrder(o); Observable<Integer> result = source.publish().refCount(); result.subscribe(o); source.onNext(1); result.subscribe(done); source.onNext(2); source.onCompleted(); inOrder.verify(o).onNext(1); inOrder.verify(o).onNext(2); inOrder.verify(o).onCompleted(); verify(o, never()).onError(any(Throwable.class)); }
@Test public void fromArityArgs1() { Observable<String> items = Observable.just("one"); assertEquals((Long) 1L, items.count().toBlocking().single()); assertEquals("one", items.takeLast(1).toBlocking().single()); }
/** * A reduce on an empty Observable and a seed should just pass the seed through. * * <p>This is confirmed at https://github.com/ReactiveX/RxJava/issues/423#issuecomment-27642456 */ @Test public void testReduceWithEmptyObservableAndSeed() { Observable<Integer> observable = Observable.range(1, 0); int value = observable.reduce(1, (t1, t2) -> t1 + t2).toBlocking().last(); assertEquals(1, value); }
@Test public void fromArray() { String[] items = new String[] {"one", "two", "three"}; assertEquals((Long) 3L, Observable.fromArray(items).count().toBlocking().single()); assertEquals("two", Observable.fromArray(items).skip(1).take(1).toBlocking().single()); assertEquals("three", Observable.fromArray(items).takeLast(1).toBlocking().single()); }
@Test public void testFirstWithPredicateOfNoneMatchingThePredicate() { Observable<Integer> observable = Observable.just(1, 3, 5, 7, 9, 7, 5, 3, 1); observable.filter(IS_EVEN).first().subscribe(w); verify(w, never()).onNext(anyInt()); verify(w, never()).onComplete(); verify(w, times(1)).onError(isA(NoSuchElementException.class)); }
@Test public void testFirstOfNone() { Observable<Integer> observable = Observable.empty(); observable.first().subscribe(w); verify(w, never()).onNext(anyInt()); verify(w, never()).onComplete(); verify(w, times(1)).onError(isA(NoSuchElementException.class)); }
@Test public void testTakeFirstOfNone() { Observable<Integer> observable = Observable.empty(); observable.take(1).subscribe(w); verify(w, never()).onNext(anyInt()); verify(w, times(1)).onComplete(); verify(w, never()).onError(any(Throwable.class)); }
@Test public void testTakeFirstWithPredicateOfNoneMatchingThePredicate() { Observable<Integer> observable = Observable.just(1, 3, 5, 7, 9, 7, 5, 3, 1); observable.takeFirst(IS_EVEN).subscribe(w); verify(w, never()).onNext(anyInt()); verify(w, times(1)).onComplete(); verify(w, never()).onError(any(Throwable.class)); }
public void testTakeFirstWithPredicateOfSome() { Observable<Integer> observable = Observable.just(1, 3, 5, 4, 6, 3); observable.takeFirst(IS_EVEN).subscribe(w); verify(w, times(1)).onNext(anyInt()); verify(w).onNext(4); verify(w, times(1)).onComplete(); verify(w, never()).onError(any(Throwable.class)); }
@Test public void testReduceWithInitialValue() { Observable<Integer> observable = Observable.just(1, 2, 3, 4); observable.reduce(50, (t1, t2) -> t1 + t2).subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyInt()); verify(w).onNext(60); }
@Test public void testCountError() { Observable<String> o = Observable.error(() -> new RuntimeException()); o.count().subscribe(w); verify(w, never()).onNext(anyInt()); verify(w, never()).onComplete(); verify(w, times(1)).onError(any(RuntimeException.class)); }
@Test public void testCountZeroItems() { Observable<String> observable = Observable.empty(); observable.count().subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyLong()); verify(w).onNext(0L); verify(w, never()).onError(any(Throwable.class)); verify(w, times(1)).onComplete(); }
@Test public void testAssert() { Observable<Integer> oi = Observable.from(Arrays.asList(1, 2)); TestSubscriber<Integer> o = new TestSubscriber<Integer>(); oi.subscribe(o); o.assertReceivedOnNext(Arrays.asList(1, 2)); assertEquals(2, o.getOnNextEvents().size()); o.assertTerminalEvent(); }
@Test public void fromIterable() { ArrayList<String> items = new ArrayList<>(); items.add("one"); items.add("two"); items.add("three"); assertEquals((Long) 3L, Observable.fromIterable(items).count().toBlocking().single()); assertEquals("two", Observable.fromIterable(items).skip(1).take(1).toBlocking().single()); assertEquals("three", Observable.fromIterable(items).takeLast(1).toBlocking().single()); }
@Test public void testCountAFewItems() { Observable<String> observable = Observable.just("a", "b", "c", "d"); observable.count().subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyLong()); verify(w).onNext(4L); verify(w, never()).onError(any(Throwable.class)); verify(w, times(1)).onComplete(); }
@Test public void testIgnoreElements() { Observable<Integer> observable = Observable.just(1, 2, 3).ignoreElements(); Subscriber<Object> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, never()).onNext(any(Integer.class)); verify(observer, never()).onError(any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testAssertNotMatchValue() { Observable<Integer> oi = Observable.from(Arrays.asList(1, 2)); TestSubscriber<Integer> o = new TestSubscriber<Integer>(); oi.subscribe(o); thrown.expect(AssertionError.class); thrown.expectMessage("Value at index: 1 expected to be [3] (Integer) but was: [2] (Integer)"); o.assertReceivedOnNext(Arrays.asList(1, 3)); assertEquals(2, o.getOnNextEvents().size()); o.assertTerminalEvent(); }
/** A reduce should fail with an NoSuchElementException if done on an empty Observable. */ @Test(expected = NoSuchElementException.class) public void testReduceWithEmptyObservable() { Observable<Integer> observable = Observable.range(1, 0); observable .reduce((t1, t2) -> t1 + t2) .toBlocking() .forEach( t1 -> { // do nothing ... we expect an exception instead }); fail("Expected an exception to be thrown"); }
@Test public void testContainsWithEmptyObservable() { Observable<Boolean> observable = Observable.<String>empty().contains("a"); Subscriber<Object> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, times(1)).onNext(false); verify(observer, never()).onNext(true); verify(observer, never()).onError(org.mockito.Matchers.any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testWrappingMock() { Observable<Integer> oi = Observable.from(Arrays.asList(1, 2)); @SuppressWarnings("unchecked") Observer<Integer> mockObserver = mock(Observer.class); oi.subscribe(new TestSubscriber<Integer>(mockObserver)); InOrder inOrder = inOrder(mockObserver); inOrder.verify(mockObserver, times(1)).onNext(1); inOrder.verify(mockObserver, times(1)).onNext(2); inOrder.verify(mockObserver, times(1)).onCompleted(); inOrder.verifyNoMoreInteractions(); }
@Test public void testAssertNotMatchCount() { Observable<Integer> oi = Observable.from(Arrays.asList(1, 2)); TestSubscriber<Integer> o = new TestSubscriber<Integer>(); oi.subscribe(o); thrown.expect(AssertionError.class); thrown.expectMessage("Number of items does not match. Provided: 1 Actual: 2"); o.assertReceivedOnNext(Arrays.asList(1)); assertEquals(2, o.getOnNextEvents().size()); o.assertTerminalEvent(); }
@Test public void testMaterializeDematerializeChaining() { Observable<Integer> obs = Observable.just(1); Observable<Integer> chained = obs.materialize().dematerialize(); Subscriber<Integer> observer = TestHelper.mockSubscriber(); chained.subscribe(observer); verify(observer, times(1)).onNext(1); verify(observer, times(1)).onComplete(); verify(observer, times(0)).onError(any(Throwable.class)); }
@Test @Ignore("null values are not allowed") public void testContainsWithNull() { Observable<Boolean> observable = Observable.just("a", "b", null).contains(null); Subscriber<Object> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, times(1)).onNext(true); verify(observer, never()).onNext(false); verify(observer, never()).onError(org.mockito.Matchers.any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testContainsWithInexistence() { Observable<Boolean> observable = Observable.just("a", "b").contains("c"); // FIXME null values are not allowed, removed Subscriber<Object> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, times(1)).onNext(false); verify(observer, never()).onNext(true); verify(observer, never()).onError(org.mockito.Matchers.any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testContains() { Observable<Boolean> observable = Observable.just("a", "b", "c").contains("b"); // FIXME nulls not allowed, changed to "c" Subscriber<Boolean> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, times(1)).onNext(true); verify(observer, never()).onNext(false); verify(observer, never()).onError(org.mockito.Matchers.any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testCreate() { Observable<String> observable = Observable.just("one", "two", "three"); Subscriber<String> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, times(1)).onNext("one"); verify(observer, times(1)).onNext("two"); verify(observer, times(1)).onNext("three"); verify(observer, never()).onError(any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testOfType() { Observable<String> observable = Observable.just(1, "abc", false, 2L).ofType(String.class); Subscriber<Object> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); verify(observer, never()).onNext(1); verify(observer, times(1)).onNext("abc"); verify(observer, never()).onNext(false); verify(observer, never()).onNext(2L); verify(observer, never()).onError(org.mockito.Matchers.any(Throwable.class)); verify(observer, times(1)).onComplete(); }
@Test public void testTakeWithErrorInObserver() { final AtomicInteger count = new AtomicInteger(); final AtomicReference<Throwable> error = new AtomicReference<>(); Observable.just("1", "2", "three", "4") .take(3) .safeSubscribe( new Observer<String>() { @Override public void onComplete() { System.out.println("completed"); } @Override public void onError(Throwable e) { error.set(e); System.out.println("error"); e.printStackTrace(); } @Override public void onNext(String v) { int num = Integer.parseInt(v); System.out.println(num); // doSomething(num); count.incrementAndGet(); } }); assertEquals(2, count.get()); assertNotNull(error.get()); if (!(error.get() instanceof NumberFormatException)) { fail("It should be a NumberFormatException"); } }
/** * https://github.com/ReactiveX/RxJava/issues/198 * * <p>Rx Design Guidelines 5.2 * * <p>"when calling the Subscribe method that only has an onNext argument, the OnError behavior * will be to rethrow the exception on the thread that the message comes out from the Observable. * The OnCompleted behavior in this case is to do nothing." * * @throws InterruptedException */ @Test @Ignore("Subscribers can't throw") public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final AtomicReference<Throwable> exception = new AtomicReference<>(); Observable.create( observer -> { new Thread( () -> { try { observer.onError(new Error("failure")); } catch (Throwable e) { // without an onError handler it has to just throw on whatever thread // invokes it exception.set(e); } latch.countDown(); }) .start(); }) .subscribe(); // wait for exception latch.await(3000, TimeUnit.MILLISECONDS); assertNotNull(exception.get()); assertEquals("failure", exception.get().getMessage()); }