Running tests on an emulator or device is slow. For Android, Robolectric brings faster and reliable unit tests because it runs on the JVM. With Robolectric, you can test Android components such as
Fragment. When you test those components, you need to consider something more because they are not a pure business logic class. For example, it could contain code for image loading using Picasso. Picasso is typically initialized in the
Suppose you want to test
MainActivity like below.
RobolectricTestRunner is specified to use Robolectric.
When you run this,
IllegalStateException happens from Picasso. The interesting thing is that
testA would pass but
testB would fail due to this exception. This is because
YourApplication is reused for each test method. Instead of destroying
YourApplication, lifecycle events(e.g.
onDestroy) are called before and after each test. Picasso doesn’t allow to call
setSingletonInstance twice so it throws an exception.
This only happens with Robolectric and never happens in your real device. To resolve this issue, you can modify
YourApplication to catch that exception and ignore it. Given that this doesn’t happen in the production environment, catching exception sounds not great. The better way is to create an application only for Robolectric. You can specify it in
RobolectricTestRunner runs, it checks this file and that application is used for testing instead of
With a static boolean value, you can prevent a double calling on
Now, let’s think about another point: network request. To show an image, that request is necessary. However, network request or disk access are not recommended while unit testing mainly for better performance. Mostly, you don’t consider image loading result. In that case, you can avoid the request by mocking Picasso.
Answers.RETURNS_MOCKS makes you avoid having lots of mocking. Without that, you need to mock every method including nested calls.
Last but not least, actually you do not need to concern on the network request. Internally, Picasso uses
DispatcherThread to load an image.
DispatcherThread has a looper to handle requests. Robolectric modifies or extends Android class behavior with Shadows. When you run with Robolectric, a looper doesn’t process any queued actions unless you proceed manually. This is an example for the main looper.
Robolectric enables you to test Android components. If Picasso is used in that component, creating
RobolectricApplication is a nice way to keep your production code clean and avoid
IllegalStateException. With Robolectric, you don’t need to worry about network request even if you use a real Picasso. If you prefer mocking, mock it with