nutella_eater
nutella_eater

Reputation: 3582

Mock Room database for Unit tests

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?

Upvotes: 11

Views: 15163

Answers (3)

Sundaravel
Sundaravel

Reputation: 494

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

Upvotes: 6

shinzlah
shinzlah

Reputation: 248

Please refer to this article. https://developer.android.com/training/data-storage/room/testing-db

It's Unit test and not slowly like UI Test as you think.

The recommended approach for testing your database implementation is writing a JUnit test that runs on an Android device. Because these tests don't require creating an activity, they should be faster to execute than your UI tests.

Upvotes: -1

tynn
tynn

Reputation: 39853

You usually access the database through the @Dao interfaces. These can be mocked easily.

The daos are returned from abstract methods of your actual RoomDatabase, so this could be mocked easily as well.

Just instantiate your RoomRepository with the mocks and setup these properly.

Upvotes: 1

Related Questions