ant2009
ant2009

Reputation: 22526

Unit testing RxJava using Single.just(true) as the expected result

Android Studio 3.0
RxJava-1

Unit testing the following code that will return a single with the result that could be either true or false depending if findLastMessage returns null or not.

 public Single<Boolean> hasLocalStorage() {
        return Single.fromCallable(() ->
                chatStorageHelper.findLatestMessage() != null);
    }

In my test case I have the following: storageHelper is a mock that will return a non-null value for this case

@Test
    public void testHasLocalStorage_hasLocalStorage_returnTrue() {
        when(storageHelper.findLatestMessage()).thenReturn(new DBMessage());

        final Single<Boolean> result = Single.just(true);
        assertThat(localRepository.hasLocalStorage(), is(result));
    }

However, the test always fails because of this:

Expected :is <rx.internal.util.ScalarSynchronousSingle@712cfb63> 
Actual   :<rx.Single@32e54a9d>

When I check what Single.just(true) returns is the following:

public static <T> Single<T> just(final T value) {
        return ScalarSynchronousSingle.create(value);
    }

Calls the ScalarSynchronousSingle. I am wondering how can I change my test case so that a rx.Single is return from Single.just(true)?

Many thanks for any suggestions,

Upvotes: 1

Views: 5257

Answers (2)

Sergej Isbrecht
Sergej Isbrecht

Reputation: 4002

This lines will not work:

assertThat(localRepository.hasLocalStorage(), is(result));

because Single is a wrapper vor a Value, which may be produce in the Future. In fact you are assert if the reference of #hasLocalStorage return value is the same as the result.

You need to get the value from the hasLocalStorage-Single and from result, and compare its values.

For example you could use #toBlocking() and leave the reactive environment with #value().

  @Test
  void name2() throws Exception {
    final Object obj = new Object();

    Single<Object> just1 = Single.just(obj);
    Single<Object> just2 = Single.just(obj);

    Object value1 = just1.toBlocking().value();
    Object value2 = just2.toBlocking().value();

    assertThat(value1).isEqualTo(value2);
  }

Upvotes: 3

cherif
cherif

Reputation: 1344

The problem is that you are trying to assert the references from two differents Single, one from your testing code and other from your production code. You will need to provide the Single from the constructor and, in your test, send it when you create that class.

Upvotes: 2

Related Questions