I'm trying to make some Unit tests for my business logic.
Data is read and written to Room database, so the logic depends on what's inside my database.
I can easily buildInMemoryDatabase
and test all the logic, but using Instrumental tests which are slow and require a device to be connected.
I want to run Unit tests only where I replace my RoomRepository
with some other implementation of Repository
interface
class RoomRepository(
private val database: RoomDatabase //actual room database
): Repository {
override fun getFooByType(type: Int): Maybe<List<Item>> {
return database.fooDao()
.getFooByType(type)
.map { names ->
names.map { name -> Item(name) }
}
.subscribeOn(Schedulers.io())
}
}
Maybe there is a way to run Room sqlite on host machine?
Maybe there is another solution?
Create a wrapper class named "Repository" around the RoomDatabase and have methods to expose the Dao objects. By that way, we can easily mock the repository class like below
Open class Repository(private val roomDatabase:RoomDatabase){
open fun productsDao():ProductsDao = roomDatabase.productDao()
open fun clientsDao():ClientsDao = roomDatabase.clientsDao()
//additional repository logic here if you want
}
Now, in tests, this class can be easily mocked like
val repositoryMock = mock(Repository::class.java)
val productsDaoMock = mock(ProductsDao::class.java)
when(repositoryMock.productsDao()).thenReturn(productsDaoMock)
when(productsDaoMock.getProducts()).thenReturn(listof("ball","pen")
So, inject and use the repository class instead of RoomDatabase class in all the places of your project so that the repository and all the Dao can be easily mocked
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With