Dependency injection in unit testing

This article will explain how to write unit tests with dependency injection (DI) using Dagger 2. I will assume you are already familiar with Mockito and Dagger 2.

Quick tip before getting started, when using Dagger 2 in a library project, instead of an application, make sure you add the following lines to your build script, if not you will not be able to use DI for unit testing.

Without these 3 line you will not be able to get your annotation processor to generate DI code for your unit tests. This took me an annoyingly long time to figure out when i first starting using Dagger DI with my unit tests. The files placed in test source sets are not added to the Java model, therefore not recognizable by Android Studio. This is a workaround until it is fixed.

The dagger dependencies are as follows:

Im my opinion, one of the easiest ways to use DI for your unit tests is to write a BaseUnitTest class, that will be extended by all of my unit tests that require DI.

From now on, we will focus on testing a ProfileManager class with a basic Dagger 2 setup. First lets take a look at the setup and the ProfileManager class before we get to the testing. If you don’t care about the setup you can skip this part.

Lets take a look at our real component (MyComponent) class

Lets take a look at the real MyApiModule

Nothing out of the ordinary.

Now lets take a look at our ProfileManager class which requires the api to be injected for later usage.

So far so good, we have all of our basic Dagger setup. The component, the api module, and the injector setup, with a ProfileManager injecting itself using the injector to get access to the MyApi class which is generated from the ApiManager class.

How do we use this in our unit tests? In our test directory, we will create a BaseUnitTest class which will contain an internal interface (doesn’t have to be internal, but it will be for this example) which mirrors the modules used in the real MyComponent interface, and extends the real MyComponent interface as well.

 

Now, inside our BaseUnitTest class lets create a setUp method to be overwritten by all of our child test classes. Inside of this setUp method we will build our component just as we would in our real injector class. The end result would look like this:

Great, so now that all the dagger setup is complete for our unit tests, lets see how we can use this!

Again, in our test directory we will create a test MyApiTestModule class to represent our mocked api module.

We want to be able to mock network calls, and the network call results. To do this we create a new class which extends the MyApiModule class and we override the provides method which returns a mocked instance of our MyApi class.

Now we add this new test module in our BaseUnitTest setUp method.

Great! now we are all done with all of our test DI setup. Lets create our ProfileManagerTest class in our test directory, like any other unit test.

Once this is done, we are pretty much done, now we can mock responses for our injected api.

That’s all it takes. Every time you want to mock some injected dependency, create a test module, pass it in to your test component and you can mock all functionality in your unit tests. I hope this was helpful, please feel free to leave any comments below.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *