NoClassDef Error In Room Unit Tests

While going through unit testing in Room, there was a particular issue I found with the dependencies needed for the tests to pass.

I’ve added a snippet of my test code which looks like this:

@RunWith(RobolectricTestRunner::class)
class CachedProjectsDaoTest {

    @Rule
    @JvmField var instantTaskExecutionRule = InstantTaskExecutorRule()

    private val database = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), ProjectsDatabase::class.java)
        .allowMainThreadQueries()
        .build()

    @After
    fun closeDb() {
        database.close()
    }

    @Test
    fun getProjectsReturnsData() {
        val project = ProjectDataFactory.makeCachedProject()
        database.cachedProjectsDao().insertProjects(listOf(project))

        val testObserver = database.cachedProjectsDao().getProjects().test()
        testObserver.assertValue(listOf(project))
    }

Using AndroidX and RxJava2, my cache layer dependencies looked correct:

cacheDependencies = [
        daggerCompiler: "com.google.dagger:dagger-compiler:$dagger_version",
        dagger: "com.google.dagger:dagger:$dagger_version",
        gson: "com.google.code.gson:gson:$gson_version",
        rxKotlin: "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version",
        kotlin: "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version",
        javaxInject: "javax.inject:javax.inject:$javaxInjectVersion",
        javaxAnnotation: "javax.annotation:javax.annotation-api:$javaxAnnotationVersion",
        androidAnnotations: "androidx.annotation:annotation:$annotations_version",
        roomRuntime: "androidx.room:room-runtime:$room_version",
        roomCompiler: "androidx.room:room-compiler:$room_version",
        roomktx: "androidx.room:room-ktx:$room_version",
        roomRxJava: "androidx.room:room-rxjava2:$room_version"
]

But this still resulted in my tests failing with a NoClassDefError. So turns out that when you migrate to AndroidX, you need the LiveData dependency even though you don’t use it at all in your testing or anywhere in your caching layer; So just proceed with adding it as a dependency:

cacheDependencies = [
        daggerCompiler: "com.google.dagger:dagger-compiler:$dagger_version",
        dagger: "com.google.dagger:dagger:$dagger_version",
        gson: "com.google.code.gson:gson:$gson_version",
        rxKotlin: "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version",
        kotlin: "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version",
        javaxInject: "javax.inject:javax.inject:$javaxInjectVersion",
        javaxAnnotation: "javax.annotation:javax.annotation-api:$javaxAnnotationVersion",
        androidAnnotations: "androidx.annotation:annotation:$annotations_version",
        roomRuntime: "androidx.room:room-runtime:$room_version",
        roomCompiler: "androidx.room:room-compiler:$room_version",
        roomktx: "androidx.room:room-ktx:$room_version",
        roomRxJava: "androidx.room:room-rxjava2:$room_version",
        livedata: "androidx.lifecycle:lifecycle-livedata:$livedata_version"
]

This then had the tests passing as normal.