RSS

Unit Testing for Android – Mockito

24 Apr

Unit testing in general is one of the after thoughts for many during the development process. I was recently reminded how important unit testing is and that it should seriously be considered when estimating time/effort during the project planning/estimation day(s) in your Agile process (you are Agile, right?).

I see unit testing being used in two ways: first, for algorithm/logic validation and secondly, for behavior validations (BDD – Behavior Driven Development).

In this post, I’m just going to illustrate how to use Mockito to validate algorithms/logic at unit(method)-level on an Android application.

The Ingredients

The following libraries are required in your test project’s classpath:

  • Mockito (as of this post mockito-1.9.5)  – link
  • DexMaker (dexmaker-1.0 and dexmaker-mockito-1.0) – link
As of 1.9.5, Mockito supports the Delvik VM by using DexMaker to generate
mock classes dynamically, allowing the unit test to run on your android 
device.

The Preparation

Test Subject

Suppose our app stores data in a SQLite database while offline. Once the app is connected, it can sync with the server.

public void syncData( final ConnectionManager connectionManager )
{
    final NetworkInfo networkInfo = connectionManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI );
    if ( networkInfo.isAvailable() && networkInfo.isConnected() ) {
        //...sync data
    }
}

Test Case Structure

When using Mockito, I find it useful to follow the Setup/Exercise/Verify pattern:

  • Setup – Setup the stub/mock objects and their behavior
  • Exercise – invoke the method(s) to tests
  • Verify – Verify that the stubs/mock objects were interacted with as expected
public class TestApplication extends AndroidTestCase {
    ...
public void testSyncData() {
    // Setup
    final ConnectivityManager connectivityManager = Mockito.mock( ConnectivityManager.class );
    final NetworkInfo networkInfo = Mockito.mock( NetworkInfo.class );
    Mockito.when( connectivityManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI ).thenReturn( networkInfo );
    Mockito.when( networkInfo.isAvailable() ).thenReturn( true );
    Mockito.when( networkInfo.isConnected() ).thenReturn( true );
    // Exercise
    syncData( connectivityManager );
    // Verify
    Mockito.verify( connectivityManager ).getNetworkInfo();
    Mockito.verify( networkInfo ).isAvailable();
    Mockito.verify( networkInfo ).isConnected();
}
}

The Execution

The final step is the run the testcase as a Android JUnit Test.  You’ll notice that a ‘Test’ APK is built and installed on your device and presents a non-destructive way of testing applicable behavior on specific devices.

Once you work more with the Mockito API, you’ll see just how powerful this tool is and how you’ll benefit from better application code structure, architecture and reliability.

In a future post, I’ll discuss how Robolectric will speed up our testing cycles.

Advertisements
 
3 Comments

Posted by on April 24, 2013 in Android

 

Tags: , , ,

3 responses to “Unit Testing for Android – Mockito

  1. Cathy

    April 29, 2013 at 16:30

    Aw, this was a really nice post. Spending some time and actual effort to create
    a really good article… but what can I say… I
    procrastinate a lot and never manage to get nearly anything done.

     
  2. Luis Barragan (@lfbarragan)

    May 2, 2013 at 14:25

    I’m getting the following error:

    Cannot load class. Make sure it is in your apk. Class name: ‘org.mockito.cglib.transform.AbstractProcessTask’.

    My test project classpath includes these three lines:

    Any clues?

     
  3. Kenneth

    August 10, 2014 at 08:19

    Hi,

    if I’m not mistaking you’re missing a closing parenthesis in your testSyncData-method:
    “Mockito.when( connectivityManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI ).thenReturn( networkInfo );” should have a closing parenthesis before the “thenReturn”-call.

    Just thought I should mention it in case others, like myself, copies you code.

    Greetings,
    Kenneth

     

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

 
%d bloggers like this: