Skip to content

Mock an Observable Interface

August 1st, 2016 - SoftwareTutorial(1 min)

TL;DR: Use a doAnswer() with a new Answer<Observable<Type>>() if you have to mock observables.

Today I wrote my first test where I had to mock an observable interface:

public interface UserDatabase {
    Observable<User> readUser(String username);
}

where the User model is:

public class User {
    private String name;
    private String password;

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public String getPassword() {
        return password;
    }
}

Solution

In my test class (named UserDatabaseTest), I first mocked the interface:

@Mock
UserDatabase mockUserDatabase;

Then, my setup() method is:

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);

    // Mock one user answer
    doAnswer(new Answer<observable<user>>() {
        @Override
        public Observable<user> answer(InvocationOnMock invocation) throws Throwable {
            return Observable.just(user);
        }
    }).when(mockUserDatabase).readUser(USER_NAME);
}

where USER_NAME is a String.

To use it, you need to attach an observer and assert:

@Test
public void canGetUser() {
    Observable<User> userObservable = mockUserDatabase.readUser(UserCommon.USER_NAME);

    TestObserver<User> userTestObserver = new TestObserver<>();
    userObservable.subscribe(userTestObserver);

    userTestObserver.assertReceivedOnNext(Collections.singletonList(user));
}

This is quite simple.

Alternative

Note: This I haven’t tried yet, but here it goes…

If you want to return a particular method call, you can use:

when(mockUserDatabase.readUser(USER_NAME))
    .thenReturn(Observable.just(new User(...)));

This is shorter (if it works) :)

HTH,

Share on
Reddit
Linked in
Whatsapp

A little experiment: