Reputation: 3840
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
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