Search code examples
kotlinjunit4android-roomkoin

Room test database implementation not found


I am testing a DAO and in order to do so, I need to extend it with a getAll() method not existing in the production code.

The only way I could think about to achieve this, is to extend my database implementation with an extended DAO containing the getAll() I need. The code looks like the following:

@Database(
                entities = [
                    OneEntity::class,
                    AnotherEntity::class
                ],
                version = 1,
                exportSchema = false
        )
        abstract class TestDatabase : RoomDatabase() {
            abstract fun getOneEntityDao(): OneEntityDao
            abstract fun getAnotherEntityDao(): TestAnotherEntityDao
        }

@Dao
abstract class TestAnotherEntityDao : AnotherEntityDao {

        @Query("""select * from $ANOTHER_ENTITY_TABLE""")
        abstract fun getAll() : Single<List<AnotherEntity>>
    }

But when I run the tests I get the following error:

`java.lang.RuntimeException: cannot find implementation for com.example.persistence.TestDatabase. TestDatabase_Impl does not exist`

I already checked other answers and the only thing that worked for me is to move the Testdatabase class out of the test directory but I'd rather prefer not to have a test class in my production code. Any ideas why is this happening and how to solve it?


Solution

  • Have you included all the necessary TestDepenedencies for the test build to recognize Room content as well as the kapt and other necessary components? I see what you are trying to do, haven't personally done it, but you are extending generated code, so that seems potentially unreliable.

    Whats the reason you don't just add a "getAll" to the standard DAO class and just only use it in tests. If you are concerned about others' touching it, you could always throw a deprecated tag over it, but the interface that exposes it all would seem like a better place for this to live with more reliable access.

    However, if you feel the query doesn't belong to either table, you could make a DAO specifically for your custom query needs. You can specify the query that the fun does. like

    @Query ( "SELECT * FROM firstTable UNION SELECT * FROM secondTable")
    fun myCombiningQueryMethod() : MyEntityArray
    

    You aren't forced to query the content of your own table as far as I know. So write as nice of query as you want and make a class for it.

    Then if you are worried about having that class in your production code, simply make a flavor. Split out the Database implementation, one flavor is for production and one is for testing where it includes the additional table.

    Hope that helps. happy coding.