簡體   English   中英

如何在單元測試中獲取上下文以在內存數據庫對象中創建 Room 數據庫

[英]How to get Context in unit test to create Room database in memory database object

我正在嘗試在執行數據庫插入的應用程序存儲庫類中測試這個函數。 我使用Koin作為我的依賴注入庫。 為了進行測試,我需要創建一個內置於內存的數據庫版本。 要創建該數據庫,我需要 Android 應用程序上下文。 所以我創建了我的測試類,如下所示。

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()
    }
}

我得到了這個例外。

java.lang.IllegalStateException:未注冊檢測! 必須在注冊檢測下運行。

如您所見,我嘗試了兩種獲取Context (檢查上面類中的注釋行),但都以相同的方式失敗。 錯誤指向了我創建Context對象的地方。 test文件夾中的這個測試類不在androidTest文件夾中。 我想把這個函數和其他將來會出現的函數分開,並在這個類中測試。

這是我的依賴項

//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'

我的依賴注入類。

val applicationModule = module {
    single { AppDatabase.getDatabaseInstance(androidContext().applicationContext) }
}

val activityModule = module {

    scope(named<MainActivity>()) {
        scoped { (activity: MainActivity) ->
            Navigation
                .findNavController(activity, R.id.hostFragment)
        }
    }
}

我是測試新手。 如果我已經掌握了單元測試的概念,請指出。 否則指出此代碼的問題。 謝謝。

在本地單元測試中使用 Robolectric 創建上下文

對於在 JVM 上運行的本地單元測試,Robolectric 有效。 如果這是在儀器測試中,則不需要 Robolectric。 InstrumentationRegistry可以在Joe Birch 的示例中使用

1. 添加庫

JUnit 5

構建.gradle

testImplementation "org.robolectric:robolectric:X.X.X"
testImplementation "androidx.test.ext:junit:X.X.X"

結界 4

內置使用 JUnit 4 和 AndroidX 庫。

2. 使用ApplicationProvider創建應用上下文

結界 5

請參閱:構建本地單元測試 > 包含框架依賴項- Android 文檔

SomeTest.kt

import androidx.test.core.app.ApplicationProvider

@RunWith(RobolectricTestRunner::class)
class SomeTest {

    @Test
    fun someTest() {
        val appContext = ApplicationProvider.getApplicationContext<Context>()
        ...
    }

}


JUnit 4

請參閱:Robolectric 的文檔

3.使用類注解@Config處理SDK 29/Java 9錯誤

請參閱:如何將 Java 9 添加到 Android Studio? - 堆棧溢出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM