├── .gitignore ├── .travis.yml ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── samples ├── build.gradle └── src │ └── test │ └── java │ └── BasicSamplesTest.java ├── settings.gradle └── src ├── main └── java │ └── com │ └── petertackage │ └── assertrx │ ├── Assertions.java │ └── TestSubscriberAssert.java └── test └── java └── com └── petertackage └── assertrx ├── TestSubscriberAssertDelegatedTest.java └── TestSubscriberAssertTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | *.class 4 | *.iml 5 | 6 | .idea/ 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | before_cache: 4 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 5 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 6 | cache: 7 | directories: 8 | - $HOME/.gradle/caches/ 9 | - $HOME/.gradle/wrapper/ 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Assert-Rx 2 | ========= 3 | 4 | DEPRECATED! 5 | 6 | As of RxJava 1.3, [fluent assertions will be part of the RxJava 1.x library](https://github.com/ReactiveX/RxJava/pull/4777/). You should use the official equivalent instead. The official assertions are assertion library agnostic and use the same API as RxJava 2.x, which should help you make the transition should you chose to. 7 | 8 | Only use this library if somehow you cannot to update to RxJava 1.3. 9 | 10 | Every library has its lifespan and this one's has ended. Thank you for your interest! 11 | 12 | A fluent assertion wrapper to simplify and improve usability of [RxJava's TestSubscriber](http://reactivex.io/RxJava/javadoc/rx/observers/TestSubscriber.html) assertions, built upon the [AssertJ](https://joel-costigliola.github.io/assertj/) framework. 13 | 14 | [![Build Status](https://travis-ci.org/peter-tackage/assert-rx.svg?branch=master)](https://travis-ci.org/peter-tackage/assert-rx) 15 | [![Jitpack](https://jitpack.io/v/peter-tackage/assert-rx.svg)](https://jitpack.io/#peter-tackage/assert-rx) 16 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-assert--rx-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/4069) 17 | # Purpose 18 | 19 | Although `TestSubscriber` provides some very handy assertions to test your Observables, it can be a bit tedious and verbose to use. For example, to test the last value in a sequence you would typically write: 20 | 21 | ```java 22 | TestSubscriber ts = ...... // subscribe to your Observable with TestSubscriber 23 | 24 | ts.assertNoErrors(); 25 | List values = ts.getOnNextEvents(); 26 | assertThat(values.get(values.size() - 1)).isEqualTo("expectedValue"); 27 | ``` 28 | 29 | This library makes this more readable by allowing you to express assertions in a fluent style: 30 | 31 | ```java 32 | TestSubscriber ts = ...... // subscribe to your Observable with TestSubscriber 33 | 34 | assertThat(ts).hasNoErrors() 35 | .hasReceivedLastValue("expectedValue"); 36 | ``` 37 | 38 | In addition to this wrapping, it provides some higher order assertions to allow for testing of specific conditions. 39 | 40 | ```java 41 | assertThat(ts).hasReceivedFirstValueWhich() 42 | .is(notEmptyOrNull()); 43 | ``` 44 | Where `notEmptyOrNull` is a reusable, [AssertJ Condition](https://joel-costigliola.github.io/assertj/assertj-core-conditions.html). 45 | 46 | # Usage 47 | 48 | Here are a few examples of the assertions performed using Assert-Rx. 49 | 50 | ## OnNext Assertions 51 | 52 | Assert that the subscriber received any single onNext value: 53 | 54 | ```java 55 | assertThat(ts).hasReceivedAnyValue(); 56 | ``` 57 | 58 | Assert that the subscriber has received one or more onNext values: 59 | 60 | ```java 61 | assertThat(ts).hasReceivedAnyValues(); 62 | ``` 63 | 64 | Multiple, in-order values: 65 | 66 | ```java 67 | assertThat(ts).hasReceivedValues("a", "b", "c"); 68 | ``` 69 | 70 | Assert conditions for single onNext events (currently only as `Object` instances): 71 | 72 | ```java 73 | assertThat(ts).hasReceivedValueWhich() 74 | .is(notEmptyOrNull()); 75 | ``` 76 | 77 | Assert conditions for the entire onNext value sequence: 78 | 79 | ```java 80 | assertThat(ts).hasReceivedValuesWhich() 81 | .doesNotContain(someObject); 82 | ``` 83 | 84 | Assert the first or last received onNext values: 85 | 86 | ```java 87 | assertThat(ts).hasReceivedFirstValue("the first value"); 88 | ``` 89 | 90 | ```java 91 | assertThat(ts).hasReceivedLastValue("the last value"); 92 | ``` 93 | 94 | ```java 95 | assertThat(ts).hasReceivedFirstValueWhich() 96 | .is(notEmptyOrNull()); 97 | ``` 98 | 99 | ```java 100 | assertThat(ts).hasReceivedLastValueWhich() 101 | .is(notEmptyOrNull()); 102 | ``` 103 | 104 | ## OnError Assertions 105 | 106 | Received an `IOException` instance in `onError`: 107 | 108 | ```java 109 | assertThat(ts).hasError(IOException.class); 110 | ``` 111 | 112 | 113 | Assert conditions for onError events (currently only as `Throwable` instances): 114 | 115 | ```java 116 | assertThat(ts).hasErrorWhich() 117 | .hasMessageStartingWith("A terrible error"); 118 | ``` 119 | 120 | ## Concurrency Handling 121 | 122 | Handle concurrency, by ensuring that the `TestSubscriber` awaits a terminal event before asserting: 123 | 124 | ```java 125 | assertThat(ts).afterTerminalEvent() 126 | .hasNoErrors() 127 | .hasReceivedValue("someValue") 128 | .hasCompleted(); 129 | ``` 130 | 131 | Download 132 | -------- 133 | 134 | Releases are available as dependencies via [Jitpack](https://jitpack.io/#peter-tackage/assert-rx/0.9.8). 135 | 136 | Implementation 137 | -------------- 138 | 139 | The library is built as an extension to the [AssertJ](https://joel-costigliola.github.io/assertj/) framework, but to avoid duplication of the assertion logic in 140 | `TestSubscriber`, in most cases it simply calls through to the `TestSubscriber` assertion methods. 141 | The exceptions to this are the higher level assertions, which are provided by returning instances of AssertJ assertions. 142 | 143 | Acknowledgements 144 | ---------------- 145 | 146 | Brought to you by the power of the [Chilicorn](http://spiceprogram.org/chilicorn-history/) and the [Futurice Open Source Program](http://spiceprogram.org/). 147 | 148 | ![Chilicorn Logo](https://raw.githubusercontent.com/futurice/spiceprogram/gh-pages/assets/img/logo/chilicorn_no_text-256.png) 149 | 150 | License 151 | ======= 152 | 153 | Copyright 2016 Peter Tackage 154 | 155 | Licensed under the Apache License, Version 2.0 (the "License"); 156 | you may not use this file except in compliance with the License. 157 | You may obtain a copy of the License at 158 | 159 | http://www.apache.org/licenses/LICENSE-2.0 160 | 161 | Unless required by applicable law or agreed to in writing, software 162 | distributed under the License is distributed on an "AS IS" BASIS, 163 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 164 | See the License for the specific language governing permissions and 165 | limitations under the License. 166 | 167 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.petertackage' 2 | version '0.9.8' 3 | 4 | apply plugin: 'java' 5 | apply plugin: "jacoco" 6 | 7 | sourceCompatibility = 1.6 8 | targetCompatibility = 1.6 9 | 10 | repositories { 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | testCompile 'junit:junit:4.12' 16 | testCompile 'org.mockito:mockito-core:2.0.52-beta' 17 | 18 | compile 'io.reactivex:rxjava:1.2.1' 19 | compile 'org.assertj:assertj-core:1.7.1' 20 | } 21 | 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peter-tackage/assert-rx/f88c13cb1396c3960768bd6477deb6b3d6d9bbc4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Apr 30 18:37:44 CEST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /samples/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | compileJava.setSourceCompatibility('1.8') 4 | compileJava.setTargetCompatibility('1.8') 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { url "https://jitpack.io" } 9 | } 10 | 11 | dependencies { 12 | compile project(':') 13 | testCompile 'junit:junit:4.12' 14 | } 15 | -------------------------------------------------------------------------------- /samples/src/test/java/BasicSamplesTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Ignore; 2 | import org.junit.Test; 3 | import rx.Observable; 4 | import rx.functions.Func1; 5 | import rx.observers.TestSubscriber; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import static com.petertackage.assertrx.Assertions.assertThat; 10 | 11 | /** 12 | * Some more real-world style test samples. 13 | *

14 | * Remove @Ignore annotations to experiment. 15 | */ 16 | public class BasicSamplesTest { 17 | 18 | @Test 19 | public void testDelay() { 20 | // Not an ideal way of testing Observables with concurrency because it will still take 2 seconds! 21 | String value = "avalue"; 22 | Observable delayObservable = Observable.just(value).delay(2, TimeUnit.SECONDS); 23 | 24 | TestSubscriber ts = TestSubscriber.create(); 25 | delayObservable.subscribe(ts); 26 | 27 | assertThat(ts) 28 | .afterTerminalEvent() 29 | .hasReceivedValue(value); 30 | } 31 | 32 | @Test 33 | public void testFiltering() { 34 | String value = "catalog"; 35 | String value2 = "caterpillar"; 36 | String value3 = "dog"; 37 | Observable filteredObservable = Observable.just(value, value2, value3) 38 | .filter(new Func1() { 39 | @Override 40 | public Boolean call(String s) { 41 | return s.startsWith("cat"); 42 | } 43 | }); 44 | 45 | TestSubscriber ts = TestSubscriber.create(); 46 | filteredObservable.subscribe(ts); 47 | 48 | assertThat(ts) 49 | .hasNoErrors() 50 | .hasReceivedValuesWhich() 51 | .containsOnly(value, value2); 52 | } 53 | 54 | @Test 55 | @Ignore("This test is intentionally failing - ignored so that the build passes") 56 | public void testFilteringEmitsUnexpectedValue() { 57 | String value = "catalog"; 58 | String value2 = "caterpillar"; 59 | String value3 = "dog"; 60 | Observable filteredObservable = Observable.just(value, value2, value3) 61 | .filter(new Func1() { 62 | @Override 63 | public Boolean call(String s) { 64 | return s.startsWith("cat"); 65 | } 66 | }); 67 | 68 | TestSubscriber ts = TestSubscriber.create(); 69 | filteredObservable.subscribe(ts); 70 | 71 | assertThat(ts) 72 | .hasNoErrors() 73 | .hasReceivedValuesWhich() 74 | .containsSequence(value, value2, value3); 75 | } 76 | 77 | @Test 78 | @Ignore("This test is intentionally failing - ignored so that the build passes") 79 | public void testFilteringErrors() { 80 | String value = "catalog"; 81 | Observable erroringFilteringObservable = Observable.just(value). 82 | concatWith(Observable.error(new NullPointerException())); 83 | 84 | TestSubscriber ts = TestSubscriber.create(); 85 | erroringFilteringObservable.subscribe(ts); 86 | 87 | assertThat(ts) 88 | .hasNoErrors() 89 | .hasReceivedValuesWhich() 90 | .containsOnly(value); 91 | } 92 | 93 | @Test 94 | @Ignore("This test is intentionally failing - ignored so that the build passes") 95 | public void testNeverErrors() { 96 | Observable empty = Observable.never(); 97 | 98 | TestSubscriber ts = TestSubscriber.create(); 99 | empty.subscribe(ts); 100 | 101 | assertThat(ts).hasTerminalEvent(); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'assert-rx' 2 | include ':samples' 3 | -------------------------------------------------------------------------------- /src/main/java/com/petertackage/assertrx/Assertions.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Peter Tackage 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.petertackage.assertrx; 17 | 18 | import rx.observers.TestSubscriber; 19 | 20 | /** 21 | * Entry point for performing {@link TestSubscriber} assertions. 22 | */ 23 | public final class Assertions { 24 | 25 | /** 26 | * Creates a new instance of {@link TestSubscriberAssert}. 27 | * 28 | * @param actual the actual value. 29 | * @return the created assertion object. 30 | */ 31 | public static TestSubscriberAssert assertThat(final TestSubscriber actual) { 32 | return new TestSubscriberAssert(actual, TestSubscriberAssert.class); 33 | } 34 | 35 | private Assertions() { 36 | throw new AssertionError("No instances."); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/petertackage/assertrx/TestSubscriberAssert.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Peter Tackage 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.petertackage.assertrx; 17 | 18 | import org.assertj.core.api.AbstractAssert; 19 | import org.assertj.core.api.AbstractListAssert; 20 | import org.assertj.core.api.AbstractObjectAssert; 21 | import org.assertj.core.api.AbstractThrowableAssert; 22 | import org.assertj.core.data.Index; 23 | import org.assertj.core.util.Objects; 24 | import rx.observers.TestSubscriber; 25 | 26 | import java.util.List; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | import static org.assertj.core.api.Assertions.assertThat; 30 | 31 | /** 32 | * Assertion methods for {@link rx.observers.TestSubscriber}s. 33 | *

34 | * To create an instance of this class, invoke {@link Assertions#assertThat(TestSubscriber)}. 35 | *

36 | */ 37 | public final class TestSubscriberAssert extends AbstractAssert, TestSubscriber> { 38 | 39 | TestSubscriberAssert(final TestSubscriber actual, final Class selfType) { 40 | super(actual, selfType); 41 | } 42 | 43 | /** 44 | * See {@link TestSubscriber#awaitTerminalEvent()} 45 | */ 46 | public TestSubscriberAssert afterTerminalEvent() { 47 | isNotNull(); 48 | actual.awaitTerminalEvent(); 49 | return this; 50 | } 51 | 52 | /** 53 | * See {@link TestSubscriber#awaitTerminalEvent(long, TimeUnit)} 54 | */ 55 | public TestSubscriberAssert afterTerminalEvent(final long timeout, final TimeUnit unit) { 56 | isNotNull(); 57 | actual.awaitTerminalEvent(timeout, unit); 58 | return this; 59 | } 60 | 61 | /** 62 | * See {@link TestSubscriber#awaitTerminalEventAndUnsubscribeOnTimeout(long, TimeUnit)} 63 | */ 64 | public TestSubscriberAssert afterTerminalEventAndUnsubscribingIfTimeout(final long timeout, final TimeUnit unit) { 65 | isNotNull(); 66 | actual.awaitTerminalEventAndUnsubscribeOnTimeout(timeout, unit); 67 | return this; 68 | } 69 | 70 | /** 71 | * See {@link TestSubscriber#assertNoValues()} 72 | */ 73 | public TestSubscriberAssert hasNoValues() { 74 | isNotNull(); 75 | actual.assertNoValues(); 76 | return this; 77 | } 78 | 79 | /** 80 | * See {@link TestSubscriber#assertReceivedOnNext(List)} 81 | */ 82 | public TestSubscriberAssert hasReceivedValues(final List values) { 83 | isNotNull(); 84 | actual.assertReceivedOnNext(values); 85 | return this; 86 | } 87 | 88 | /** 89 | * See {@link TestSubscriber#assertReceivedOnNext(List)} 90 | */ 91 | public TestSubscriberAssert hasReceivedValues(final T... values) { 92 | isNotNull(); 93 | actual.assertValues(values); 94 | return this; 95 | } 96 | 97 | /** 98 | * See {@link TestSubscriber#assertValue(Object)} 99 | */ 100 | public TestSubscriberAssert hasReceivedValue(final T value) { 101 | isNotNull(); 102 | actual.assertValue(value); 103 | return this; 104 | } 105 | 106 | /** 107 | * Passes when {@link TestSubscriber} has received one or more {@link TestSubscriber#onNext(Object)} events. 108 | * 109 | * @return this {@link TestSubscriberAssert} 110 | */ 111 | public TestSubscriberAssert hasReceivedAnyValues() { 112 | isNotNull(); 113 | List actualEvents = actual.getOnNextEvents(); 114 | assertThat(actualEvents) 115 | .overridingErrorMessage("Expected received onNext events not to be empty.") 116 | .isNotEmpty(); 117 | return this; 118 | } 119 | 120 | /** 121 | * Passes when {@link TestSubscriber} has received a single {@link TestSubscriber#onNext(Object)} events. 122 | * 123 | * @return this {@link TestSubscriberAssert} 124 | */ 125 | public TestSubscriberAssert hasReceivedAnyValue() { 126 | isNotNull(); 127 | List actualEvents = actual.getOnNextEvents(); 128 | assertThat(actualEvents) 129 | .overridingErrorMessage("Expected received onNext events not to be empty.") 130 | .isNotEmpty() 131 | .overridingErrorMessage("Expected a single onNext value, but was: <%s>.", actualEvents) 132 | .hasSize(1); 133 | return this; 134 | } 135 | 136 | /** 137 | * Passes when the {@link TestSubscriber}'s first received event is equal to the provided value. 138 | * 139 | * @param value the expected first received onNext value. 140 | * @return this {@link TestSubscriberAssert} 141 | */ 142 | public TestSubscriberAssert hasReceivedFirstValue(final T value) { 143 | isNotNull(); 144 | List received = actual.getOnNextEvents(); 145 | assertThat(received) 146 | .overridingErrorMessage("Expected received onNext events not to be empty.") 147 | .isNotEmpty() 148 | .overridingErrorMessage("Expected first received onNext event to be: <%s>, but was: <%s>.", 149 | value, 150 | firstValueOf(received)) 151 | .contains(value, Index.atIndex(0)); 152 | return this; 153 | } 154 | 155 | /** 156 | * Passes when the {@link TestSubscriber}'s last received event is equal to the provided value. 157 | * 158 | * @param value the expected last received onNext value. 159 | * @return this {@link TestSubscriberAssert} 160 | */ 161 | public TestSubscriberAssert hasReceivedLastValue(final T value) { 162 | isNotNull(); 163 | List received = actual.getOnNextEvents(); 164 | assertThat(received) 165 | .overridingErrorMessage("Expected received onNext events not to be empty.") 166 | .isNotEmpty() 167 | .overridingErrorMessage("Expected last received onNext event to be: <%s>, but was: <%s>.", 168 | value, 169 | lastValueOf(received)) 170 | .contains(value, Index.atIndex(lastIndexOf(received))); 171 | return this; 172 | } 173 | 174 | /** 175 | * Returns a {@link AbstractAssert} for higher order assertions on the single received onNext value. 176 | */ 177 | public AbstractObjectAssert hasReceivedValueWhich() { 178 | isNotNull(); 179 | List received = actual.getOnNextEvents(); 180 | assertThat(received) 181 | .overridingErrorMessage("Expected a single onNext value, but was: <%s>.", received) 182 | .hasSize(1); 183 | return assertThat(firstValueOf(received)); 184 | } 185 | 186 | /** 187 | * Returns a {@link AbstractAssert} for higher order assertions on the first received onNext value. 188 | */ 189 | public AbstractObjectAssert hasReceivedFirstValueWhich() { 190 | isNotNull(); 191 | List received = actual.getOnNextEvents(); 192 | assertThat(received) 193 | .overridingErrorMessage("Expected received onNext events not to be empty.") 194 | .isNotEmpty(); 195 | return assertThat(firstValueOf(received)); 196 | } 197 | 198 | /** 199 | * Returns a {@link AbstractAssert} for higher order assertions on the last received onNext value. 200 | */ 201 | public AbstractObjectAssert hasReceivedLastValueWhich() { 202 | isNotNull(); 203 | List received = actual.getOnNextEvents(); 204 | assertThat(received) 205 | .overridingErrorMessage("Expected received onNext events not to be empty.") 206 | .isNotEmpty(); 207 | return assertThat(lastValueOf(received)); 208 | } 209 | 210 | /** 211 | * Returns an {@link AbstractListAssert} for higher order assertions on the received onNext values. 212 | */ 213 | public AbstractListAssert, T> hasReceivedValuesWhich() { 214 | isNotNull(); 215 | return assertThat(actual.getOnNextEvents()); 216 | } 217 | 218 | /** 219 | * See {@link TestSubscriber#assertValueCount(int)} 220 | */ 221 | public TestSubscriberAssert hasValueCount(final int count) { 222 | isNotNull(); 223 | actual.assertValueCount(count); 224 | return this; 225 | } 226 | 227 | /** 228 | * See {@link TestSubscriber#assertCompleted()} 229 | */ 230 | public TestSubscriberAssert hasCompleted() { 231 | isNotNull(); 232 | actual.assertCompleted(); 233 | return this; 234 | } 235 | 236 | /** 237 | * See {@link TestSubscriber#assertNotCompleted()} 238 | */ 239 | public TestSubscriberAssert hasNotCompleted() { 240 | isNotNull(); 241 | actual.assertNotCompleted(); 242 | return this; 243 | } 244 | 245 | /** 246 | * See {@link TestSubscriber#assertNoErrors()} 247 | */ 248 | public TestSubscriberAssert hasNoErrors() { 249 | isNotNull(); 250 | actual.assertNoErrors(); 251 | return this; 252 | } 253 | 254 | /** 255 | * See {@link TestSubscriber#assertError(Throwable)} 256 | */ 257 | public TestSubscriberAssert hasError(final Throwable throwable) { 258 | isNotNull(); 259 | assertThat(throwable).isNotNull(); 260 | actual.assertError(throwable); 261 | return this; 262 | } 263 | 264 | /** 265 | * See {@link TestSubscriber#assertError(Class)} 266 | */ 267 | public TestSubscriberAssert hasError(final Class clazz) { 268 | isNotNull(); 269 | assertThat(clazz).isNotNull(); 270 | actual.assertError(clazz); 271 | return this; 272 | } 273 | 274 | /** 275 | * Returns an {@link AbstractThrowableAssert} for higher order assertions on the single received onError value. 276 | */ 277 | public AbstractThrowableAssert hasErrorWhich() { 278 | isNotNull(); 279 | List received = actual.getOnErrorEvents(); 280 | assertThat(received) 281 | .overridingErrorMessage("Expected a single onError event, but was: <%s>.", received) 282 | .hasSize(1); 283 | return assertThat(firstValueOf(received)); 284 | } 285 | 286 | /** 287 | * See {@link TestSubscriber#assertTerminalEvent()} 288 | */ 289 | public TestSubscriberAssert hasTerminalEvent() { 290 | isNotNull(); 291 | actual.assertTerminalEvent(); 292 | return this; 293 | } 294 | 295 | /** 296 | * See {@link TestSubscriber#assertNoTerminalEvent()} 297 | */ 298 | public TestSubscriberAssert hasNoTerminalEvent() { 299 | isNotNull(); 300 | actual.assertNoTerminalEvent(); 301 | return this; 302 | } 303 | 304 | /** 305 | * See {@link TestSubscriber#assertUnsubscribed()} 306 | */ 307 | public TestSubscriberAssert isUnsubscribed() { 308 | isNotNull(); 309 | actual.assertUnsubscribed(); 310 | return this; 311 | } 312 | 313 | /** 314 | * Passes when the {@link TestSubscriber}'s last seen thread (refer {@link TestSubscriber#lastSeenThread}) 315 | * is equal to the supplied {@link Thread} parameter. 316 | * 317 | * @param thread the expected last seen {@link Thread} 318 | * @return this {@link TestSubscriberAssert} 319 | */ 320 | public TestSubscriberAssert wasLastObservedOn(final Thread thread) { 321 | isNotNull(); 322 | final Thread lastSeenThread = actual.getLastSeenThread(); 323 | if (!Objects.areEqual(lastSeenThread, thread)) { 324 | failWithMessage("Expected to be observed on: <%s>, was observed on: <%s>.", thread, lastSeenThread); 325 | } 326 | return this; 327 | } 328 | 329 | private static T firstValueOf(List received) { 330 | return received.get(0); 331 | } 332 | 333 | private static T lastValueOf(List received) { 334 | return received.get(lastIndexOf(received)); 335 | } 336 | 337 | private static int lastIndexOf(List received) { 338 | return received.size() - 1; 339 | } 340 | 341 | } 342 | -------------------------------------------------------------------------------- /src/test/java/com/petertackage/assertrx/TestSubscriberAssertDelegatedTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Peter Tackage 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.petertackage.assertrx; 17 | 18 | import org.junit.Rule; 19 | import org.junit.Test; 20 | import org.junit.rules.ExpectedException; 21 | import org.mockito.Matchers; 22 | import rx.Observable; 23 | import rx.observers.TestSubscriber; 24 | 25 | import java.util.Arrays; 26 | import java.util.Collections; 27 | import java.util.List; 28 | import java.util.concurrent.TimeUnit; 29 | 30 | import static org.mockito.Matchers.eq; 31 | import static org.mockito.Mockito.*; 32 | 33 | public class TestSubscriberAssertDelegatedTest { 34 | 35 | @Rule 36 | public ExpectedException thrown = ExpectedException.none(); 37 | 38 | // Delegated tests - only test that the appropriate TestSubscriber assert method is invoked. 39 | 40 | @Test 41 | public void afterTerminalEvent_invokesTestSubscriberAwaitTerminalEvent() { 42 | //noinspection unchecked 43 | TestSubscriber ts = mock(TestSubscriber.class); 44 | 45 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).afterTerminalEvent(); 46 | 47 | verify(ts).awaitTerminalEvent(); 48 | } 49 | 50 | @Test 51 | public void afterTerminalEventWithTimeout_invokesTestSubscriberAwaitTerminalEvent() { 52 | //noinspection unchecked 53 | TestSubscriber ts = mock(TestSubscriber.class); 54 | long timeoutValue = 5; 55 | TimeUnit unitValue = TimeUnit.DAYS; 56 | 57 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).afterTerminalEvent(timeoutValue, unitValue); 58 | 59 | verify(ts).awaitTerminalEvent(eq(timeoutValue), eq(unitValue)); 60 | } 61 | 62 | @Test 63 | public void afterTerminalEventAndUnsubscribingIfTimeout_invokesTestSubscriberAwaitTerminalEvent() { 64 | //noinspection unchecked 65 | TestSubscriber ts = mock(TestSubscriber.class); 66 | long timeoutValue = 5; 67 | TimeUnit unitValue = TimeUnit.DAYS; 68 | 69 | new TestSubscriberAssert(ts, TestSubscriberAssert.class) 70 | .afterTerminalEventAndUnsubscribingIfTimeout(timeoutValue, unitValue); 71 | 72 | verify(ts).awaitTerminalEventAndUnsubscribeOnTimeout(eq(timeoutValue), eq(unitValue)); 73 | } 74 | 75 | 76 | @Test 77 | public void hasNoValues_invokesTestSubscribeAssertNoValues() { 78 | //noinspection unchecked 79 | TestSubscriber ts = mock(TestSubscriber.class); 80 | 81 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasNoValues(); 82 | 83 | verify(ts).assertNoValues(); 84 | } 85 | 86 | @Test 87 | public void hasReceivedValue_invokesTestSubscriberAssertValue() { 88 | Integer value = 1; 89 | Observable oi = Observable.just(value); 90 | //noinspection unchecked 91 | TestSubscriber ts = mock(TestSubscriber.class); 92 | oi.subscribe(ts); 93 | 94 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValue(value); 95 | 96 | verify(ts).assertValue(eq(value)); 97 | } 98 | 99 | @Test 100 | public void hasReceivedValues_invokesTestSubscriberAssertReceivedOnNextValue_whenMultiple() { 101 | List values = Arrays.asList(1, 2, 3); 102 | Observable oi = Observable.from(values); 103 | // Requires spy as decoration of TestSubscriber as Subscriber accesses TestSubscriber instance internals 104 | // which are not initialized when using a mock. 105 | TestSubscriber ts = spy(new TestSubscriber()); 106 | oi.subscribe(ts); 107 | 108 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValues(values); 109 | 110 | verify(ts).assertReceivedOnNext(eq(values)); 111 | } 112 | 113 | @Test 114 | public void hasReceivedValuesVarArgs_invokesTestSubscriberAssertValues_whenMultiple() { 115 | Integer[] values = {1, 2, 3}; 116 | Observable oi = Observable.from(values); 117 | //noinspection unchecked 118 | TestSubscriber ts = mock(TestSubscriber.class); 119 | oi.subscribe(ts); 120 | 121 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValues(1, 2, 3); 122 | 123 | verify(ts).assertValues(Matchers.anyVararg()); 124 | } 125 | 126 | @Test 127 | public void hasValueCount_invokesTestSubscriberAssertValueCount() { 128 | List values = Arrays.asList(1, 2, 3); 129 | Observable oi = Observable.from(values); 130 | // Requires spy as decoration of TestSubscriber as Subscriber accesses TestSubscriber instance internals 131 | // which are not initialized when using a mock. 132 | TestSubscriber ts = spy(new TestSubscriber()); 133 | oi.subscribe(ts); 134 | 135 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasValueCount(values.size()); 136 | 137 | verify(ts).assertValueCount(eq(values.size())); 138 | } 139 | 140 | @Test 141 | public void hasCompleted_invokesTestSubscriberAssertCompleted() { 142 | //noinspection unchecked 143 | TestSubscriber ts = mock(TestSubscriber.class); 144 | 145 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasCompleted(); 146 | 147 | verify(ts).assertCompleted(); 148 | } 149 | 150 | @Test 151 | public void hasNotCompleted_invokesTestSubscriberAssertNotCompleted() { 152 | //noinspection unchecked 153 | TestSubscriber ts = mock(TestSubscriber.class); 154 | 155 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasNotCompleted(); 156 | 157 | verify(ts).assertNotCompleted(); 158 | } 159 | 160 | @Test 161 | public void hasNoErrors_invokesTestSubscriberAssertNoErrors() { 162 | //noinspection unchecked 163 | TestSubscriber ts = mock(TestSubscriber.class); 164 | 165 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasNoErrors(); 166 | 167 | verify(ts).assertNoErrors(); 168 | } 169 | 170 | @Test 171 | public void hasTerminalEvent_invokesTestSubscriberAssertTerminalEvent() { 172 | //noinspection unchecked 173 | TestSubscriber ts = mock(TestSubscriber.class); 174 | 175 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasTerminalEvent(); 176 | 177 | verify(ts).assertTerminalEvent(); 178 | } 179 | 180 | @Test 181 | public void hasNoTerminalEvent_invokesTestSubscriberAssertNoTerminalEvent() { 182 | //noinspection unchecked 183 | TestSubscriber ts = mock(TestSubscriber.class); 184 | 185 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasNoTerminalEvent(); 186 | 187 | verify(ts).assertNoTerminalEvent(); 188 | } 189 | 190 | @Test 191 | public void isUnsubscribed_invokesTestSubscriberAssertUnsubscribed() { 192 | //noinspection unchecked 193 | TestSubscriber ts = mock(TestSubscriber.class); 194 | 195 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).isUnsubscribed(); 196 | 197 | verify(ts).assertUnsubscribed(); 198 | } 199 | 200 | @Test 201 | public void hasErrorInstance_invokesTestSubscriberAssertErrorInstance() { 202 | Throwable throwable = new Throwable(); 203 | Observable oi = Observable.error(throwable); 204 | // Requires spy as decoration of TestSubscriber as Subscriber accesses TestSubscriber instance internals 205 | // which are not initialized when using a mock. 206 | TestSubscriber ts = spy(new TestSubscriber()); 207 | oi.subscribe(ts); 208 | 209 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasError(throwable); 210 | 211 | verify(ts).assertError(eq(throwable)); 212 | } 213 | 214 | @Test 215 | public void hasErrorClass_invokesTestSubscriberAssertErrorClass() { 216 | Throwable throwable = new Throwable(); 217 | Observable oi = Observable.error(throwable); 218 | // Requires spy as decoration of TestSubscriber as Subscriber accesses TestSubscriber instance internals 219 | // which are not initialized when using a mock. 220 | TestSubscriber ts = spy(new TestSubscriber()); 221 | oi.subscribe(ts); 222 | 223 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasError(throwable.getClass()); 224 | 225 | verify(ts).assertError(eq(throwable.getClass())); 226 | } 227 | 228 | } 229 | -------------------------------------------------------------------------------- /src/test/java/com/petertackage/assertrx/TestSubscriberAssertTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Peter Tackage 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.petertackage.assertrx; 17 | 18 | import org.assertj.core.api.AbstractListAssert; 19 | import org.assertj.core.api.AbstractObjectAssert; 20 | import org.junit.Rule; 21 | import org.junit.Test; 22 | import org.junit.rules.ExpectedException; 23 | import rx.Observable; 24 | import rx.observers.TestSubscriber; 25 | 26 | import java.util.Arrays; 27 | import java.util.Collections; 28 | import java.util.List; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | import static org.mockito.Mockito.mock; 32 | import static org.mockito.Mockito.when; 33 | 34 | public class TestSubscriberAssertTest { 35 | 36 | @Rule 37 | public ExpectedException thrown = ExpectedException.none(); 38 | 39 | // Higher Order tests - these don't use TestSubscriber assertions. 40 | 41 | // hasReceivedFirstValue 42 | 43 | @Test 44 | public void hasReceivedFirstValue_doesNotAssert_whenSourceObservableEmitsOnceEqual() { 45 | Object value = new Object(); 46 | Observable oi = Observable.just(value); 47 | TestSubscriber ts = new TestSubscriber(); 48 | oi.subscribe(ts); 49 | 50 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(value); 51 | } 52 | 53 | @Test 54 | public void hasReceivedFirstValue_doesNotAssert_whenSourceObservableEmitsMultipleFirstEqual() { 55 | Object value = new Object(); 56 | Observable oi = Observable.just(value, new Object()); 57 | TestSubscriber ts = new TestSubscriber(); 58 | oi.subscribe(ts); 59 | 60 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(value); 61 | } 62 | 63 | @Test 64 | public void hasReceivedFirstValue_asserts_whenSourceObservableEmitsMultipleFirstNotEqualAndOtherValueEquals() { 65 | Object value = new Object(); 66 | Object otherValue = new Object(); 67 | expectAssertionErrorWithMessage(String.format("Expected first received onNext event to be: <%s>, but was: <%s>.", otherValue, value)); 68 | Observable oi = Observable.just(value, otherValue); 69 | TestSubscriber ts = new TestSubscriber(); 70 | oi.subscribe(ts); 71 | 72 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(otherValue); 73 | } 74 | 75 | @Test 76 | public void hasReceivedFirstValue_asserts_whenSourceObservableEmitsOnceNotEqual() { 77 | Object otherValue = new Object(); 78 | Object value = new Object(); 79 | expectAssertionErrorWithMessage(String.format("Expected first received onNext event to be: <%s>, but was: <%s>.", otherValue, value)); 80 | Observable oi = Observable.just(value); 81 | TestSubscriber ts = new TestSubscriber(); 82 | oi.subscribe(ts); 83 | 84 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(otherValue); 85 | } 86 | 87 | @Test 88 | public void hasReceivedFirstValue_asserts_whenSourceObservableIsEmpty() { 89 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 90 | Observable oi = Observable.empty(); 91 | TestSubscriber ts = new TestSubscriber(); 92 | oi.subscribe(ts); 93 | 94 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(new Object()); 95 | } 96 | 97 | @Test 98 | public void hasReceivedFirstValue_asserts_whenNotEqual_andSourceObservableEmitsMultiple() { 99 | Object otherValue = new Object(); 100 | Object value = new Object(); 101 | expectAssertionErrorWithMessage(String.format("Expected first received onNext event to be: <%s>, but was: <%s>", otherValue, value)); 102 | Observable oi = Observable.just(value, otherValue); 103 | TestSubscriber ts = new TestSubscriber(); 104 | oi.subscribe(ts); 105 | 106 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValue(otherValue); 107 | } 108 | 109 | // hasReceivedLastValue 110 | 111 | @Test 112 | public void hasReceivedLastValue_doesNotAssert_whenSourceObservableEmitsOnceEqual() { 113 | Object value = new Object(); 114 | Observable oi = Observable.just(value); 115 | TestSubscriber ts = new TestSubscriber(); 116 | oi.subscribe(ts); 117 | 118 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(value); 119 | } 120 | 121 | @Test 122 | public void hasReceivedLastValue_doesNotAssert_whenSourceObservableEmitsMultipleLastEqual() { 123 | Object value = new Object(); 124 | Observable oi = Observable.just(new Object(), value); 125 | TestSubscriber ts = new TestSubscriber(); 126 | oi.subscribe(ts); 127 | 128 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(value); 129 | } 130 | 131 | @Test 132 | public void hasReceivedLastValue_asserts_whenSourceObservableEmitsMultipleLastValueNotEqualsOtherEquals() { 133 | Object value = new Object(); 134 | Object otherValue = new Object(); 135 | expectAssertionErrorWithMessage(String.format("Expected last received onNext event to be: <%s>, but was: <%s>.", otherValue, value)); 136 | Observable oi = Observable.just(otherValue, value); 137 | TestSubscriber ts = new TestSubscriber(); 138 | oi.subscribe(ts); 139 | 140 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(otherValue); 141 | } 142 | 143 | @Test 144 | public void hasReceivedLastValue_asserts_whenSourceObservableEmitsOnceNotEqual() { 145 | Object otherValue = new Object(); 146 | Object value = new Object(); 147 | expectAssertionErrorWithMessage(String.format("Expected last received onNext event to be: <%s>, but was: <%s>.", otherValue, value)); 148 | Observable oi = Observable.just(value); 149 | TestSubscriber ts = new TestSubscriber(); 150 | oi.subscribe(ts); 151 | 152 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(otherValue); 153 | } 154 | 155 | @Test 156 | public void hasReceivedLastValue_asserts_whenSourceObservableIsEmpty() { 157 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 158 | Observable oi = Observable.empty(); 159 | TestSubscriber ts = new TestSubscriber(); 160 | oi.subscribe(ts); 161 | 162 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(new Object()); 163 | } 164 | 165 | @Test 166 | public void hasReceivedLastValue_asserts_whenSourceObservableEmitsMultipleOtherEquals() { 167 | Object otherValue = new Object(); 168 | Object value = new Object(); 169 | expectAssertionErrorWithMessage(String.format("Expected last received onNext event to be: <%s>, but was: <%s>", otherValue, value)); 170 | Observable oi = Observable.just(otherValue, value); 171 | TestSubscriber ts = new TestSubscriber(); 172 | oi.subscribe(ts); 173 | 174 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValue(otherValue); 175 | } 176 | 177 | // hasReceivedAnyValues 178 | 179 | @Test 180 | public void hasReceivedAnyValues_asserts_whenSourceObservableIsEmpty() { 181 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 182 | Observable oi = Observable.empty(); 183 | TestSubscriber ts = new TestSubscriber(); 184 | oi.subscribe(ts); 185 | 186 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValues(); 187 | } 188 | 189 | @Test 190 | public void hasReceivedAnyValues_asserts_whenSourceObservableIsError() { 191 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 192 | Observable oi = Observable.error(new Throwable()); 193 | TestSubscriber ts = new TestSubscriber(); 194 | oi.subscribe(ts); 195 | 196 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValues(); 197 | } 198 | 199 | @Test 200 | public void hasReceivedAnyValues_asserts_whenSourceObservableIsNever() { 201 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 202 | Observable oi = Observable.never(); 203 | TestSubscriber ts = new TestSubscriber(); 204 | oi.subscribe(ts); 205 | 206 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValues(); 207 | } 208 | 209 | @Test 210 | public void hasReceivedAnyValues_doesNotAssert_whenSourceObservableEmitsOnce() { 211 | Observable oi = Observable.just(1); 212 | TestSubscriber ts = new TestSubscriber(); 213 | oi.subscribe(ts); 214 | 215 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValues(); 216 | } 217 | 218 | @Test 219 | public void hasReceivedAnyValues_doesNotAssert_whenSourceObservableEmitsMultiple() { 220 | Integer[] values = {1, 2}; 221 | Observable oi = Observable.from(values); 222 | TestSubscriber ts = new TestSubscriber(); 223 | oi.subscribe(ts); 224 | 225 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValues(); 226 | } 227 | 228 | // hasReceivedAnyValue 229 | 230 | @Test 231 | public void hasReceivedAnyValue_asserts_whenSourceObservableIsEmpty() { 232 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 233 | Observable oi = Observable.empty(); 234 | TestSubscriber ts = new TestSubscriber(); 235 | oi.subscribe(ts); 236 | 237 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValue(); 238 | } 239 | 240 | @Test 241 | public void hasReceivedAnyValue_asserts_whenSourceObservableIsError() { 242 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 243 | Observable oi = Observable.error(new Throwable()); 244 | TestSubscriber ts = new TestSubscriber(); 245 | oi.subscribe(ts); 246 | 247 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValue(); 248 | } 249 | 250 | @Test 251 | public void hasReceivedAnyValue_asserts_whenSourceObservableIsNever() { 252 | expectAssertionErrorWithMessage("Expected received onNext events not to be empty."); 253 | Observable oi = Observable.never(); 254 | TestSubscriber ts = new TestSubscriber(); 255 | oi.subscribe(ts); 256 | 257 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValue(); 258 | } 259 | 260 | @Test 261 | public void hasReceivedAnyValue_doesNotAssert_whenSourceObservableEmitsOnce() { 262 | Observable oi = Observable.just(1); 263 | TestSubscriber ts = new TestSubscriber(); 264 | oi.subscribe(ts); 265 | 266 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValue(); 267 | } 268 | 269 | @Test 270 | public void hasReceivedAnyValue_asserts_whenSourceObservableEmitsMultiple() { 271 | List values = Arrays.asList(1, 2); 272 | expectAssertionErrorWithMessage(String.format("Expected a single onNext value, but was: <%s>.", values)); 273 | Observable oi = Observable.from(values); 274 | TestSubscriber ts = new TestSubscriber(); 275 | oi.subscribe(ts); 276 | 277 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedAnyValue(); 278 | } 279 | 280 | // hasReceivedValueWhich 281 | 282 | @Test 283 | public void hasReceivedValueWhich_asserts_whenOnNextEventsListIsEmpty() { 284 | List values = Collections.emptyList(); 285 | expectAssertionErrorWithMessage(String.format("Expected a single onNext value, but was: <%s>", values)); 286 | //noinspection unchecked 287 | TestSubscriber ts = mock(TestSubscriber.class); 288 | when(ts.getOnNextEvents()).thenReturn(values); 289 | 290 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValueWhich(); 291 | } 292 | 293 | @Test 294 | public void hasReceivedValueWhich_asserts_whenMultipleOnNextEvents() { 295 | List values = Arrays.asList(new Object(), new Object()); 296 | expectAssertionErrorWithMessage(String.format("Expected a single onNext value, but was: <%s>", values)); 297 | //noinspection unchecked 298 | TestSubscriber ts = mock(TestSubscriber.class); 299 | when(ts.getOnNextEvents()).thenReturn(values); 300 | 301 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValueWhich(); 302 | } 303 | 304 | @Test 305 | public void hasReceivedValueWhich_doesNotAssert_whenSingleOnNextEvent() { 306 | //noinspection unchecked 307 | TestSubscriber ts = mock(TestSubscriber.class); 308 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 309 | 310 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValueWhich(); 311 | } 312 | 313 | // hasReceivedValuesWhich 314 | 315 | @Test 316 | public void hasReceivedValuesWhich_returnsNonNullInstance_whenOnNextEventsListIsEmpty() { 317 | //noinspection unchecked 318 | TestSubscriber ts = mock(TestSubscriber.class); 319 | when(ts.getOnNextEvents()).thenReturn(Collections.emptyList()); 320 | 321 | AbstractListAssert, Object> instance = 322 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValuesWhich(); 323 | 324 | assertThat(instance).isNotNull(); 325 | } 326 | 327 | @Test 328 | public void hasReceivedValuesWhich_doesNotAssert_whenOnNextEventsListIsEmpty() { 329 | //noinspection unchecked 330 | TestSubscriber ts = mock(TestSubscriber.class); 331 | when(ts.getOnNextEvents()).thenReturn(Collections.emptyList()); 332 | 333 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValuesWhich(); 334 | } 335 | 336 | @Test 337 | public void hasReceivedValuesWhich_doesNotAssert_whenMultipleOnNextEvents() { 338 | //noinspection unchecked 339 | TestSubscriber ts = mock(TestSubscriber.class); 340 | when(ts.getOnNextEvents()).thenReturn(Arrays.asList(new Object(), new Object())); 341 | 342 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValuesWhich(); 343 | } 344 | 345 | @Test 346 | public void hasReceivedValuesWhich_doesNotAssert_whenSingleOnNextEvent() { 347 | //noinspection unchecked 348 | TestSubscriber ts = mock(TestSubscriber.class); 349 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 350 | 351 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedValuesWhich(); 352 | } 353 | 354 | // hasReceivedFirstValueWhich 355 | 356 | @Test 357 | public void hasReceivedFirstValueWhich_returnsNonNullAssertionInstance() { 358 | //noinspection unchecked 359 | TestSubscriber ts = mock(TestSubscriber.class); 360 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 361 | 362 | AbstractObjectAssert instance = 363 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValueWhich(); 364 | 365 | assertThat(instance).isNotNull(); 366 | } 367 | 368 | @Test 369 | public void hasReceivedFirstValueWhich_doesNotAssert_whenSingleOnNextEvent() { 370 | //noinspection unchecked 371 | TestSubscriber ts = mock(TestSubscriber.class); 372 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 373 | 374 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValueWhich(); 375 | } 376 | 377 | @Test 378 | public void hasReceivedFirstValueWhich_doesNotAssert_whenMultipleSingleOnNextEvent() { 379 | //noinspection unchecked 380 | TestSubscriber ts = mock(TestSubscriber.class); 381 | when(ts.getOnNextEvents()).thenReturn(Arrays.asList(new Object(), new Object())); 382 | 383 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValueWhich(); 384 | } 385 | 386 | @Test 387 | public void hasReceivedFirstValueWhich_doesNotAssert_whenMultipleOnNextEvents() { 388 | //noinspection unchecked 389 | TestSubscriber ts = mock(TestSubscriber.class); 390 | when(ts.getOnNextEvents()).thenReturn(Arrays.asList(new Object(), new Object())); 391 | 392 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedFirstValueWhich(); 393 | } 394 | 395 | // hasReceivedLastValueWhich 396 | 397 | @Test 398 | public void hasReceivedLastValueWhich_returnsNonNullAssertionInstance() { 399 | //noinspection unchecked 400 | TestSubscriber ts = mock(TestSubscriber.class); 401 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 402 | 403 | AbstractObjectAssert instance = 404 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValueWhich(); 405 | 406 | assertThat(instance).isNotNull(); 407 | } 408 | 409 | @Test 410 | public void hasReceivedLastValueWhich_doesNotAssert_whenSingleOnNextEvent() { 411 | //noinspection unchecked 412 | TestSubscriber ts = mock(TestSubscriber.class); 413 | when(ts.getOnNextEvents()).thenReturn(Collections.singletonList(new Object())); 414 | 415 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValueWhich(); 416 | } 417 | 418 | @Test 419 | public void hasReceivedLastValueWhich_doesNotAssert_whenMultipleSingleOnNextEvent() { 420 | //noinspection unchecked 421 | TestSubscriber ts = mock(TestSubscriber.class); 422 | when(ts.getOnNextEvents()).thenReturn(Arrays.asList(new Object(), new Object())); 423 | 424 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValueWhich(); 425 | } 426 | 427 | @Test 428 | public void hasReceivedLastValueWhich_doesNotAssert_whenMultipleOnNextEvents() { 429 | //noinspection unchecked 430 | TestSubscriber ts = mock(TestSubscriber.class); 431 | when(ts.getOnNextEvents()).thenReturn(Arrays.asList(new Object(), new Object())); 432 | 433 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasReceivedLastValueWhich(); 434 | } 435 | 436 | // hasErrorWhich 437 | 438 | @Test 439 | public void hasErrorWhich_asserts_whenErrorEventListIsEmpty() { 440 | List values = Collections.emptyList(); 441 | expectAssertionErrorWithMessage(String.format("Expected a single onError event, but was: <%s>", values)); 442 | //noinspection unchecked 443 | TestSubscriber ts = mock(TestSubscriber.class); 444 | when(ts.getOnErrorEvents()).thenReturn(values); 445 | 446 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasErrorWhich(); 447 | } 448 | 449 | @Test 450 | public void hasErrorWhich_asserts_whenMultipleErrorEvents() { 451 | List values = Arrays.asList(new Throwable(), new Throwable()); 452 | expectAssertionErrorWithMessage(String.format("Expected a single onError event, but was: <%s>", values)); 453 | //noinspection unchecked 454 | TestSubscriber ts = mock(TestSubscriber.class); 455 | when(ts.getOnErrorEvents()).thenReturn(values); 456 | 457 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasErrorWhich(); 458 | } 459 | 460 | @Test 461 | public void hasErrorWhich_doesNotAssert_whenSingleErrorEvent() { 462 | //noinspection unchecked 463 | TestSubscriber ts = mock(TestSubscriber.class); 464 | when(ts.getOnErrorEvents()).thenReturn(Collections.singletonList(new Throwable())); 465 | 466 | new TestSubscriberAssert(ts, TestSubscriberAssert.class).hasErrorWhich(); 467 | } 468 | 469 | private void expectAssertionErrorWithMessage(final String message) { 470 | thrown.expect(AssertionError.class); 471 | thrown.expectMessage(message); 472 | } 473 | 474 | } 475 | --------------------------------------------------------------------------------