diff --git a/src/main/java/io/reactivex/observers/BaseTestConsumer.java b/src/main/java/io/reactivex/observers/BaseTestConsumer.java
index 6e1693bb18..cebb70d7c0 100644
--- a/src/main/java/io/reactivex/observers/BaseTestConsumer.java
+++ b/src/main/java/io/reactivex/observers/BaseTestConsumer.java
@@ -522,6 +522,21 @@ public final U assertValues(T... values) {
return (U)this;
}
+ /**
+ * Assert that the TestObserver/TestSubscriber received only the specified values in the specified order without terminating.
+ * @param values the values expected
+ * @return this;
+ * @since 2.1.4
+ */
+ @SuppressWarnings("unchecked")
+ @Experimental
+ public final U assertValuesOnly(T... values) {
+ return assertSubscribed()
+ .assertValues(values)
+ .assertNoErrors()
+ .assertNotComplete();
+ }
+
/**
* Assert that the TestObserver/TestSubscriber received only the specified values in any order.
*
This helps asserting when the order of the values is not guaranteed, i.e., when merging
diff --git a/src/test/java/io/reactivex/observers/TestObserverTest.java b/src/test/java/io/reactivex/observers/TestObserverTest.java
index 095e3d171f..2a34a98650 100644
--- a/src/test/java/io/reactivex/observers/TestObserverTest.java
+++ b/src/test/java/io/reactivex/observers/TestObserverTest.java
@@ -1439,4 +1439,66 @@ public void withTag() {
assertTrue(ex.toString(), ex.toString().contains("testing with item=2"));
}
}
+
+ @Test
+ public void assertValuesOnly() {
+ TestObserver to = TestObserver.create();
+ to.onSubscribe(Disposables.empty());
+ to.assertValuesOnly();
+
+ to.onNext(5);
+ to.assertValuesOnly(5);
+
+ to.onNext(-1);
+ to.assertValuesOnly(5, -1);
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsOnUnexpectedValue() {
+ TestObserver to = TestObserver.create();
+ to.onSubscribe(Disposables.empty());
+ to.assertValuesOnly();
+
+ to.onNext(5);
+ to.assertValuesOnly(5);
+
+ to.onNext(-1);
+
+ try {
+ to.assertValuesOnly(5);
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsWhenCompleted() {
+ TestObserver to = TestObserver.create();
+ to.onSubscribe(Disposables.empty());
+
+ to.onComplete();
+
+ try {
+ to.assertValuesOnly();
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsWhenErrored() {
+ TestObserver to = TestObserver.create();
+ to.onSubscribe(Disposables.empty());
+
+ to.onError(new TestException());
+
+ try {
+ to.assertValuesOnly();
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
}
diff --git a/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java b/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java
index 470f5a2308..39a384168d 100644
--- a/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java
+++ b/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java
@@ -1997,4 +1997,66 @@ public void waitStrategyRuns() {
ws.run();
}
}
+
+ @Test
+ public void assertValuesOnly() {
+ TestSubscriber ts = TestSubscriber.create();
+ ts.onSubscribe(new BooleanSubscription());
+ ts.assertValuesOnly();
+
+ ts.onNext(5);
+ ts.assertValuesOnly(5);
+
+ ts.onNext(-1);
+ ts.assertValuesOnly(5, -1);
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsOnUnexpectedValue() {
+ TestSubscriber ts = TestSubscriber.create();
+ ts.onSubscribe(new BooleanSubscription());
+ ts.assertValuesOnly();
+
+ ts.onNext(5);
+ ts.assertValuesOnly(5);
+
+ ts.onNext(-1);
+
+ try {
+ ts.assertValuesOnly(5);
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsWhenCompleted() {
+ TestSubscriber ts = TestSubscriber.create();
+ ts.onSubscribe(new BooleanSubscription());
+
+ ts.onComplete();
+
+ try {
+ ts.assertValuesOnly();
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assertValuesOnlyThrowsWhenErrored() {
+ TestSubscriber ts = TestSubscriber.create();
+ ts.onSubscribe(new BooleanSubscription());
+
+ ts.onError(new TestException());
+
+ try {
+ ts.assertValuesOnly();
+ fail();
+ } catch (AssertionError ex) {
+ // expected
+ }
+ }
}