2

Mockito on Android

 2 years ago
source link: https://developer.squareup.com/blog/mockito-on-android/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
October 22nd, 2012 | 3 minute read

Mockito on Android

Unit testing Android apps with Mockito and DexMaker.

Twitter
Facebook
Reddit
LinkedIn

Written by Jesse Wilson.

At Square we love unit tests. Our comprehensive test suite helps us to develop Android apps with confidence.

But without proper tools many scenarios are cumbersome to unit test. For example, suppose we want to pump up the device’s volume in Square Wallet. We have a method that cranks the ringer up to eleven unless the phone is silent:

**public** **void** **maximizeVolume(**AudioManager audioManager**)** **{**
  **if** **(**audioManager**.**getRingerMode**()** **!=** RINGER_MODE_SILENT**)** **{**
    **int** max **=** audioManager**.**getStreamMaxVolume**(**STREAM_RING**);**
    audioManager**.**setStreamVolume**(**STREAM_RING**,** max**,** 0**);**
  **}**
**}**

We’d like to test that this method does the right thing in all situations. If the phone is silent then the volume should not be changed. Otherwise the volume should be set to whatever getStreamMaxVolume() returned.

Manually testing scenarios like these is strenuous and error-prone. Unit testing usually requires ugly and brittle boilerplate to intercept the AudioManager APIs. Mock objects make testing easy by allowing you to script responses and validate interactions.

Mockito is my favorite library for testing with mock objects. Its fluent API separates pre-test preparation from post-test validation. Should the test fail, Mockito makes it clear to see where our expectations differ from reality! The library has everything you need to write complete tests.

A new feature in Mockito 1.9.5 is support for Android’s Dalvik runtime. It uses DexMaker to generate mock classes on the fly. To use Mockito on a device or emulator, you’ll need to add three .jar files to your test project’s libs directory: mockito-all-1.9.5.jar, dexmaker-1.0.jar, and dexmaker-mockito-1.0.jar.

Mockito tests have three parts:

  1. Prepare the mocks and script their behavior.
  2. Test the code of interest. When this code calls a method on the mock, the mock will consult its script and respond accordingly. If it has nothing scripted, it returns a default value like 0 or null.
  3. Validate that the mocks saw what they were expecting to see. And also that they didn’t see anything unexpected!

This example code tests one of the scenarios above:

**public** **void** **testSilentRingerIsNotDisturbed()** **{**
  *// 1. Prepare mocks and script their behavior.*
  AudioManager audioManager **=** Mockito**.**mock**(**AudioManager**.**class**);**
  Mockito**.**when**(**audioManager**.**getRingerMode**())**
      **.**thenReturn**(**RINGER_MODE_SILENT**);**

  // 2. Test the code of interest.
  maximizeVolume(audioManager);

  // 3. Validate that we saw exactly what we wanted.
  Mockito.verify(audioManager).getRingerMode();
  Mockito.verifyNoMoreInteractions(audioManager);
}

Mockito’s fluent API may take some getting used to! Its methods like when() and verify() use some clever Java generics to achieve both readability and type safety. Once you’re comfortable with this approach, use static imports to make the code even more fluent:

import static org**.**mockito**.**Mockito**.*;**

...

public void testNormalRingerIsMaximized() {
  // 1. Prepare mocks and script their behavior.
  AudioManager audioManager = mock(AudioManager.class);
  when(audioManager.getRingerMode()).thenReturn(RINGER_MODE_NORMAL);
  when(audioManager.getStreamMaxVolume(STREAM_RING)).thenReturn(100);

  // 2. Test the code of interest.
  maximizeVolume(audioManager);

  // 3. Validate that we saw exactly what we wanted.
  verify(audioManager).setStreamVolume(STREAM_RING, 100, 0);
}

We’ve created a simple test that always works, regardless of how the device is configured. Since the test only ever interacts with a mock audio manager, the device itself is not impacted by tests: no more missed phone calls after running JUnit!

Mock objects are a powerful tool for scenario testing. Learn more about mock object patterns (and antipatterns!) on Martin Fowler’s Mocks Aren’t Stubs article. See the Mockito site for specific APIs and examples. Jesse Wilson Android and jokes.medium.com

Picture of Square Engineering

By Square Engineering
@SquareEngMedium


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK