Robolectric: unit testing made easy

Vikram Bhati
4 min readApr 2, 2021

--

In android development, most of the time we keep writing tests as backlog tasks only, we all know that building a feature is faster than writing a test.

Of course, writing tests is a boring, time-consuming task, so most of the time we discard it from our project plan. But it's a really important part of the android development process and nowadays it has become much easier than before.

As we know that running tests on an android device or emulator is slow. Building, deploying, and launching the app often takes a minute or more. That’s no way to do TDD. Robolectric is a framework that brings fast and reliable unit tests to Android. Tests run inside the JVM on your workstation in seconds.

In short, robolectric test can be described like —

JUnit + mocked android platform dependencies + run on JVM on the workstation

Robolectric tests don’t need an emulator that makes tests faster and this can easily be integrated into your CI (Continuous Integration) pipeline running on a regular JVM.

But before that, we need to understand where Robolectric fits in the android testing paradigm? Your testing plan should be in below order —

  1. Pure unit tests (50%)
  2. Robolectric (30%)
  3. An Android testing framework like espresso, UI-Automator (20%)

The tests get harder/slower the higher the tier, but sometimes you need it. So in a nutshell, you should prefer unit tests as much as possible, and wherever you get some android related dependencies then you can consider robolectric there.

Robolectric framework has shadow classes for all android platform-related classes. And when you execute any robolectric test on JVM then it resolves all android platform dependencies using these shadow classes. This also helps us in avoiding excessive stubbing which we do while mocking platform-related code. You can check these shadow classes on this Github link.

For example, if you have used AlarmManager then you should be aware that using AlarmManager you can set up various types of alarms e.g. onetime alarm, repeating alarm, exact alarm, etc. If you are needed this class in your test then robolectric has ShadowAlarmManager which gets invoked automatically in your test. This ShadowAlarmManager has all API that exists in AlarmManager -

But it might happen that you won’t get shadow class for all platform classes because it is still in active development from the community and then you will have to write it your own.

In my project, I had to write a test for a function that fetches advertising id.

public AdvertisingIdClient.Info getAdvertisingID(final Context context) {
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
} catch (Exception e) {
Log.printStackTrace(e);
}
return adInfo;
}

I had to test if the context is not null then we should get a valid advertising id.

@Test
public void test_when_context_is_not_null_then_valid_get_advertising_id() {

AdvertisingIdClient.Info adId = new AdIdHelper().getAdvertisingID(context);
assertThat(adId).isNotNull();
assertThat(adId.getId()).isEqualTo("dsf0e47-90s4-4d5d-4949-6d0ba49dc350");

}

But this test was failing because robolectric doesn’t have a shadow class for AdvertisingIdClient.Info which exists in the play-services-ads library. I was getting below error -

com.google.android.gms.common.GooglePlayServicesNotAvailableException
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zza(Unknown Source)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(Unknown Source)

So I had to write my own Shadow class for it like below -

@Implements(AdvertisingIdClient.class)
public class ShadowAdvertisingIdClient {

public static Info getAdvertisingIdInfo(Context var0) throws IOException, IllegalStateException,
GooglePlayServicesNotAvailableException, GooglePlayServicesRepairableException {

return new Info("dsf0e47-90s4-4d5d-4949-6d0ba49dc350", false);
}

}

And that I used for my test and it ran successfully.

So yeah, using robolectric you can easily write unit tests in a faster way, not much to worry about android-related dependencies.

Though you might face some issues while setting it up due to lack of proper documentation but once it's done, then it will make your life easier and awesome. 😊

Let me know if you have any questions in the comments below and hit like if this article helped you. Until next time, stay safe and take care!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Vikram Bhati
Vikram Bhati

Responses (1)

Write a response