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

To use Hilt in your tests, include the hilt-android-testing dependency in your project.

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.

Now you can perform UI testing with Hilt but would need a few setup like annotating the testing class with @HiltAndroidTest which it needs to generate all the corresponding Hilt codes for the test. You need to add HiltAndroidRule to the test class. It manages the test states and performs injection on your test.

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.

If you are using roboelectric to test the UI layer then you can specify which application to use in the robolectric.properties file:

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.

Use the @BindValue annotation to easily bind fields in your test into the Hilt dependency graph. Annotate a field with @BindValue and it will be bound under the declared field type with any qualifiers that are present for that field.

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

Custom application for tests

If you cannot use HiltTestApplication because your test application needs to extend another application, annotate a new class or interface with @CustomTestApplication, passing in the value of the base class you want the generated Hilt application to extend.

@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

https://developer.android.com/training/dependency-injection/hilt-testing#kotlin

Senior Android Developer at ECOM Trading