Reputation: 3397
I'm trying to test a Room database in Android, written in Kotlin, locally; that is not on an emulator and without instrumented testing. As I understand it this is possible using the Roboelectric framework but I'm having some trouble with this :
How does one select the appropriate class for the RunWith(CLASS)
decorator ?
I understand AndroidJUnit4
is necessary for instrumented tests, given that this is a local test should I be using JUnit4
instead or some other derivative from RoboElectric.
How should I correctly determine the context
?
Trying InstrumentationRegistry.getTargetContext()
requires that I use InstrumentationRegistry
which isn't available when testing locally or that test
can not be imported when importing androidx.test.platform.app.InstrumentationRegistry
or android.support.test.InstrumentationRegistry
. Trying ApplicationProvider.getApplicationContext()
claims the reference getApplicationContext
can't be found. I'm also not sure where I should be importing either InstrumentationRegistry
or ApplicationProvider
from.
In general I'm finding it tricky to determine the appropriate libraries to use in Java; all the documentation appears very version specific and assumes you magically know where to import a given class from where often such a classes appear in more then one library. Then package imported through gradle also seems to be well related but does not explicitly match the package being imported. If you have any general tips on this I would be quite keen to hear it.
My code so far is as follows:
package com.manaikan.airvendor.AirTime
import android.content.Context
import android.arch.persistence.room.Room
import androidx.test.platform.app.InstrumentationRegistry
import com.manaikan.airvendor.airtime.AirVendorDatabase
import com.manaikan.airvendor.airtime.BundleQuery
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.io.IOException
// Roboelectric
import androidx.test.core.app.ApplicationProvider
@RunWith(JUnit4::class)
class BundleTest {
private lateinit var queryset : ENTITYDao
private lateinit var database : APPLICATIONDatabase
@Before
fun setup()
{
val context = ApplicationProvider.getApplicationContext<Context>()
database = Room.inMemoryDatabaseBuilder(context, APPLICATIONDatabase::class.java)
.allowMainThreadQueries()
.build()
queryset = database.bundleQuery()
}
@After
@Throws(IOException::class)
fun tearDown()
{
database.close()
}
@Test
@Throws(Exception::class)
fun review()
{
}
}
Upvotes: 1
Views: 1323
Reputation: 1346
It seems to me you were almost there. The main thing to change is the runner, use: AndroidJUnit4
, and maybe the version of the dependencies. Assuming your database and DAO are set up correctly, this should work (add import for your classes):
package com.manaikan.airvendor.AirTime
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException
@RunWith(AndroidJUnit4::class)
class BundleTest {
private lateinit var queryset : ChannelProgramsDao
private lateinit var database : ChannelProgramsDatabase
@Before
fun setup()
{
val context = ApplicationProvider.getApplicationContext<Context>()
database = Room.inMemoryDatabaseBuilder(context, APPLICATIONDatabase::class.java)
.allowMainThreadQueries()
.build()
queryset = database.bundleQuery()
}
@After
@Throws(IOException::class)
fun tearDown()
{
database.close()
}
@Test
@Throws(Exception::class)
fun review()
{
}
}
It worked for me with the following dependencies:
testImplementation "org.robolectric:robolectric:4.2"
testImplementation "androidx.test.ext:junit:4.12"
implementation "androidx.room:room-runtime:2.2.2"
implementation "androidx.room:room-ktx:2.2.2"
kapt "androidx.room:room-compiler:2.2.2"
testImplementation "androidx.room:room-testing:2.2.2"
Upvotes: 2