3Answers
  • 7
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

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?

      • 2
    • Are you able to access the database in your test cases? I am getting java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.io.File.getPath()' on a null object reference error when I create the object of Dao class. What could be the issue?

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.

  • 1
Reply Report
      • 2
    • It's unit testing. The data is never stored. The mock provides test data and you can verify function calls. You don't have to concern yourself with how the database actually works. For this you can use Mockito or Mockk on Kotlin.

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.

  • 0
Reply Report
      • 2
    • You aren't answering his question he's asking how room database can be mocked for unit tests, hes not trying to test the database itself. Thats what the article you posted refers to.

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

  • 0
Reply Report