Android Unit testing with Junit4 and Mockito

Finally , Android Studio 1.1 and the Android gradle plugin bring support for unit testing . We no longer need to run our tests on an actual device, we will be able to execute the tests against the JVM, making them much faster. This was previously possible using robolectric, but I always found it a hussle to setup on different projects.

So why should we test our code ?

enter image description here

First of all tests (unit tests, integration tests, whatever) are not like cake frosting, You don’t add them at the end. Tests are written during the development process, not at the end of it. So you will need to plan ahead, and write code while constantly having testability in mind. Which is a good “problem” to have.

But, why should you even bother writing unit tests ?

  • unit testing will “force” you to write loosely coupled code
  • gives you confidence in your code / system
  • fast, automated regression
  • easily improve and refactor your code without breaking it
  • provide documentation, because they show how the code should be used and how it should behave

What is basically a unit test :

  • written by the programmer
  • runs fast (no Network, DB, File access)
  • small scope, focused on a smart part of the software

If you are still not convinced, here is why I write tests :

  • too lazy to manually test
  • I hate regression testing
  • don’t trust QA to properly test all the cases
  • don’t trust other developers changes
  • I wan’t to be able to do a change on Friday at 6:00 PM, publish it, and have a relaxing weekend

enter image description here

To get started with unit testing on Android make sure you follow these steps. Basically you need to :

  • make sure you use build tools 1.1.0 or newer
classpath ''
  • add those dependencies to your build.gradle
 testCompile 'junit:junit:4.12'
 testCompile 'org.mockito:mockito-core:1.9.5'
  • as this is an “experimental feature” for now, go to Settings>Gradle>Experimental and check Enable Unit Testing support
  • create a folder src/test/java/ and place your unit tests there
  • to Run your tests in Android Studio, select Test Artifact : Unit Tests and then right-click your test class or package and select Run

Here is an example from a sample project I made to highlight the benefits of tests in your Android app.

public class DefaultUserManager implements UserManager {
    private static final String KEY_USER = "key_user";
    private final AccountManager accountManager;
    private final SharedPreferences preferences;

    public DefaultUserManager(AccountManager accountManager, SharedPreferences preferences) {
        this.accountManager = accountManager;
        this.preferences = preferences;
    public void setUser(@NonNull User user) {
        if (user.getUserName() == null || user.getUserName().isEmpty()) {
            throw new IllegalArgumentException("Username can not be null or empty");
        if (user.getAuthToken() == null || user.getAuthToken().isEmpty()) {
            throw new IllegalArgumentException("Auth token can not be null or empty");
        preferences.edit().putString(KEY_USER, new Gson().toJsonTree(user).toString()).commit();
        Account account = new Account(user.getUserName(), CleanAuthenticator.TYPE);
        accountManager.addAccountExplicitly(account, "no_pass", null);
        accountManager.setAuthToken(account, CleanAuthenticator.TOKEN_WRITE, user.getAuthToken());

And now a part of the unit test for it :

public class DefaultUserManagerTest {
    DefaultUserManager testedUserManager;

    SharedPreferences preferences;
    AccountManager accountManager;
    SharedPreferences.Editor editor;

    ///some setup code omitted

    public void testSetUserWillPersistToSharedPreferences() {
        //when - adding a new user
        //verify - preferences are updated
        verify(preferences, atLeastOnce()).edit();
        //verify - changed to preferences are committed
        verify(editor, atLeastOnce()).commit();

    public void testSetUserWillAddAndroidAccount() {
        //when - adding a new user
        //verify -that a user was also added to the Android account manager
        verify(accountManager, times(1))
                .addAccountExplicitly(any(Account.class), anyString(), any(Bundle.class));

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidUserThrowsException() {
        //when - adding an invalid user
    //some more omitted, boilerplate code...

So with 3 small, easy to read and maintain methods, I have tested my setUser() method. This is how the setUser() method is supposed to work, and this is how all the classes interacting with my UserManager.setUser() method expect it to work.

Obviously in time I will need to improve this code, re-factor it, change it, and this can and will break some things. But, I will have the confidence of my unit tests, I’ll just run them in a few seconds, see if anythings is broken, and if not I can publish my changes, and get back to … YouTube.

Of course, there are multiple cases that will need integration tests, and even manual test, but unit tests will find errors early, will save you a ton of time and also drive good design in your code.


About Ovidiu

Passionate Android Developer. What else? Snowboarding. Football. Stuff like that.
This entry was posted in Android. Bookmark the permalink.

1 Response to Android Unit testing with Junit4 and Mockito

  1. Thanks for posting this. I was overthinking adding Mockito to Android unit testing, glad to see it’s pretty easy.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s