Testing with Hilt android

This video has a visual implementation of what we talked about in this tutorial. Watch and subscribe please.

Testing is one of the major requirements that is needed by every developer in order to have a maintainable code base. As the project grows, the business requirements get to be more and as a result, we will need to rely on testing. This is to make sure that we stay confident whenever a change is added to the project without breaking the existing code flow or structure.

Nevertheless, testing can also be a pain when you have to write code and also write its tests especially when there is a lot of dependencies in a code unit you are performing a test on. Normally, we avoid this pain when you follow TDD architecture, where it requires you to write the test first before writing the actual code implementation and I have found this helpful.

I will like to bring to you a very good companion library when it comes to testing and it does not do the testing itself but handles the dependency injection. Let’s start talking about Hilt test.

Adding Hilt Testing Dependencies to Gradle

NB: If you use Jetpack integrations, you must also include the annotation processors for the integrated libraries with kaptTest or kaptAndroidTest for Kotlin, or with testAnnotationProcessor or androidTestAnnotationProcessor for Java.

Performing UI Testing

Hilt needs Application class in the library and you must execute your instrumented test with an application that supports Hilt. As a result, Hilt library has a HiltTestApplicationclass and would need to configure a new test runner that uses Hilt test application. Add the new test runner in the gradle config block.

Using Roboelectric Test

application = dagger.hilt.android.testing.HiltTestApplication

You can alternatively configure Roboelectric using the @Config annotation.

Now ready to use Hilt to inject dependencies in our test classes. To inject types into a test, use @Inject for field injection. To tell Hilt to populate the @Inject fields, call hiltRule.inject().

In testing sometimes, the dependencies used in the production codes might be different dependencies you would like to add in the testing code. In this case, you can do just that with Hilt. For example in production code, you have a module like below setup that provide a dependency.

In testing, you can provide a fake dependency with the use of Hilt by doing something like this by replacing the module used in the production.

But what if you want to replace this production module in only one test class, then you can do so with @UninstallModules annotation and create a new test module inside the test.

As Hilt creates new components for tests that use @UninstallModules, it can significantly impact unit test build times. Use it when necessary and prefer using @TestInstallIn when the bindings need to be replaced in all test classes.

Binding new values

In the AnalyticsService example, you can replace AnalyticsService with a fake by using @BindValue.

Custom application for tests

@CustomTestApplication will generate an Application class ready for testing with Hilt that extends the application you passed as a parameter.

I hope you find this useful and you can show your appreciation by sharing and following.

References

Senior Android Developer at ECOM Trading