I'm trying to test this one function in my application repository class which performs a database insertion. I'm using Koin
as my dependency injection library. To do the testing I need to create a Database version that gets built in memory. To create that database I need the Android application context. So I created my test class like below.
import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry
import com.chathuranga.shan.mycontacts.di.applicationModule
import com.chathuranga.shan.mycontacts.di.repositoryModule
import com.chathuranga.shan.mycontacts.room.AppDatabase
import org.junit.After
import org.junit.Test
import org.junit.Before
import org.junit.Rule
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
import org.koin.test.KoinTest
import org.koin.test.inject
import org.mockito.MockitoAnnotations
class ContactRepositoryTest : KoinTest {
private val contactRepository: ContactRepository by inject()
private lateinit var appDatabase: AppDatabase
@get:Rule
val rule = InstantTaskExecutorRule()
@Before
fun setUp() {
startKoin {
printLogger()
modules(listOf(applicationModule,repositoryModule))
}
MockitoAnnotations.initMocks(this)
val context = ApplicationProvider.getApplicationContext<Context>()
//val instrumentationContext = InstrumentationRegistry.getInstrumentation().targetContext
appDatabase = Room
.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.allowMainThreadQueries()
.build()
loadKoinModules(module { single(override = true) { appDatabase } })
}
@Test
fun insertContact() {
val firstName = "Chathuranga"
val secondName = "Shan"
val phone = "07711247890"
contactRepository.insertContact(firstName,secondName,phone,null,null)
}
@After
fun tearDown() {
stopKoin()
}
}
And I'm getting this exception.
java.lang.IllegalStateException: No instrumentation registered! Must run under registering instrumentation.
As you can see I tried two ways to get Context
(check the commented line in above class) and both failed the same way. And error pointed to the place where I create Context
object. This test class in test
folder not in androidTest
folder. I want to separate this function and other functions that gonna come in the future and test in this class.
Here are my dependencies
//Testing
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-core:2.21.0"
testImplementation 'android.arch.core:core-testing:1.1.1'
testImplementation 'androidx.test:core:1.2.0'
testImplementation 'org.koin:koin-test:2.0.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
My dependency injection class.
val applicationModule = module {
single { AppDatabase.getDatabaseInstance(androidContext().applicationContext) }
}
val activityModule = module {
scope(named<MainActivity>()) {
scoped { (activity: MainActivity) ->
Navigation
.findNavController(activity, R.id.hostFragment)
}
}
}
I'm new to testing. If the way I have grasped the concept of unit testing please point it out. Otherwise Point out the problem with this code. Thanks.