cscan
cscan

Reputation: 3840

Non Instrumentation Tests for Room Database

I'm writing tests (not instrumentation tests) for the service layer. I'd like to use the actual DAO layer instead of mocks as this makes service layer tests more functional (IMHO). I know how to create an in-memory room db for an instrumentation test:

val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build()

However, this won't work in the other tests as the call to getApplicationContext makes a call to the InstrumentationRegistry which won't work in non-instrumentation tests. I realize that the room tests should be instrumentation tests; they are. All DAO tests are instrumentation tests which aim to test out the queries which have been written. I also realize that these aren't technically unit tests; I'm okay with that. In my experience, service layer tests which do not mock the repository layer are less brittle than those which do. Anyway, my question is - how can I accomplish this goal? Is there a way to retrieve the application context without instrumentation? Is there a room db stand-in that doesn't require the application context? Or do I need to implement another version of the DAO classes for the tests?

Upvotes: 3

Views: 850

Answers (1)

atotalnoob
atotalnoob

Reputation: 268

robolectric will allow you to run this kind of test.

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [27])
class Db {
    private lateinit var db: AppDatabase
    private lateinit var myDao: myDaoType

    @Before
    fun createDB() {
        val context = InstrumentationRegistry.getInstrumentation().targetContext
        db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
            .fallbackToDestructiveMigration().allowMainThreadQueries().build()
        myDao = db.myDao()
    }

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

Upvotes: 5

Related Questions