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
orkaptAndroidTest
for Kotlin, or withtestAnnotationProcessor
orandroidTestAnnotationProcessor
for Java.
Performing UI Testing
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 HiltTestApplication
class 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
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.
Binding new values
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