This post is published at Android Weekly.
In this post i am going to explain how to use Dagger 2 in Android Tests and how Dagger 2 helps us in writing tests. I created a sample project for that: https://github.com/maydin/DaggerTesting. I will explain this project in this post. I will give some new info about adding Dagger 2 to your project but will not explain all details because there are many tutorials that explains it.
As you see in the above code, you can add Dagger 2 support by adding dagger dependencies. You see that i used Android annotationProcessor in order to add Dagger. With Gradle Plugin version 2.2.0-alpha1 or higher, you can use annotationProcessor for compile time annotation processing. Before that Dagger 2 setup was different. Another good news is that you can also use Jack&Jill, which means you can have Java 8 support with Dagger 2. In order to use Dagger 2 in Android tests, we add Dagger dependencies with androidTestAnnotationProcessor and androidTestCompile. We add Espresso dependencies,too.
Suppose that there are REST APIs that you use in your project. And you use Retrofit as your REST API client. You need to mock those APIs in order to make your tests work. In this sample project i assume that there are login and logout REST services. Below you can see the Dagger 2 Component and Module for this:
login and logout methods returns a String. When login button is clicked, login service is called and prints screen the login String: Logged in. And when logout button is clicked, prints screen Logged out. We are going to write an Espresso test that will test whether this scenario works as intended. Below is the Activity of the app:
Firstly lets see how our Application class looks like:
As you see in the code above, there is setUserComponent method which sets the Dagger Component used by the app. In the test, we will use this method to inject Test Component. With the help of @VisibleForTesting, this method is only visible for test.
Now everything is ready for the test part
Below is the test code. Firstly,have look at it and then i will explain the code:
Firstly, UserService is implemented as TestUserService. Here we mock the REST api. login and logout methods now return Test Logged in and Test Logged out. Secondly, we create a TestUserModule which returns a TestUserService instance. Then we extend UserComponent and use TestUserModule as module. Finally, in beforeActivityLaunched method, we set the app component to TestUserComponent. By this way, TestUserComponent will be used as Dagger component in the test. When you run the test, you will see that Test Logged in is printed to the screen instead of just Logged in. So the test above will pass when you run it.