How to replace bindings for Tests using Hilt
There are three ways to replace bindings in tests using Hilt
While testing our code, we always need some test data to write tests on. We don’t use production data for our testing so we prepare our fake data and provide binding to replace dependency with our fake or mock data.
Hilt provides three ways to achieve this
@TestModuleIn
— its used to replace a module with test module which contains bindings for tests, it replaces bindings for all of test classes.@UninstallModules
— If you want to replace bindings only in a single test.@BindValue
— Its used to bind a single field in a test class.
@TestModuleIn
Create a Hilt module in test
or android
and annotate it with @TestModule
It will replace production module with test module.It replaces modules for all of test classes.
Above code is replacing production module RepositoryModule with the test module RepositoryTestModule annotated with @TestModuleIn
. It will replace for all of test cases.
@UinstallModules
To replace a Hilt module only in a single test class use annotation @UninstallModules
on top of the file providing production module name that you want to replace in that test class. Then inside test class provide new test module using @InstallIn
annotation
Above example is uninstalling production Module RepositoryModule and replacing it with RepsitoryTestModule in single test file. articlesRepository property will automatically binding with FakeArticlesRepositoryImplementation
You can use @UninstallModules
only on a module which is annotated with @InstallIn
If module is not previously annotated with @InstallIn
you will get compilation error.
You can not use @UninstallModules
on a module which was annotated with @TestInstallIn
, doing so will also give compilation error
@BindValue
To replace bindings in single test file/class you can use @BindValue
. You still have to uninstall production module using annotation @UninstallModules
. @UninstallModules
annotation should be use on top of the test class declaration.
Recommendation
There are three ways to replace bindings but which one should be used?
- If you have to use test bindings in more than one test classes then you must use
@TestModuleIn
to replace whole module for all of the test classes. - If you have to replace bindings just in a single test class, then I will recommend to use
@BindValue
as it keeps code clean and simple.