Тестирование базы данных комнаты с помощью Coroutine - PullRequest
0 голосов
/ 26 мая 2020

Я использую Coroutine для вставки, извлечения данных из базы данных комнат, и я пишу тест для своего Dao, но я сталкиваюсь с некоторыми проблемами, подобными этому.

@RunWith(RobolectricTestRunner::class)
class PersistenceLayerTest {

    lateinit var currencyDatabase: CurrencyDatabase

    lateinit var currencyDao: CurrencyDao

    lateinit var timestampDao: TimestampDao

    lateinit var localRepository: LocalRepository

    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    val testCoroutineDispatcher = TestCoroutineDispatcher()

    val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)

    @Before
    fun initDb() {
        currencyDatabase = Room.inMemoryDatabaseBuilder(
            InstrumentationRegistry.getInstrumentation().targetContext, CurrencyDatabase::class.java
        )
            .setTransactionExecutor(testCoroutineDispatcher.asExecutor())
            .setQueryExecutor(testCoroutineDispatcher.asExecutor())
            .allowMainThreadQueries()
            .build()

        currencyDao = currencyDatabase.currencyDao()

        timestampDao = currencyDatabase.timestampDao()

        localRepository = LocalRepository(currencyDao, timestampDao)
    }

    @Test
    fun insertCurrency() {
        val currency = Currency(
            flag = 1211, exchangeRate = "1200", currencyName = "Dollar", timestamp = "1137187182192", shortName = "USD"
        )
        val currency1 = Currency(
            flag = 1211, exchangeRate = "1200", currencyName = "Dollar", timestamp = "1137187182192", shortName = "USD"
        )
        TestCoroutineScope().launch {
            currencyDao.saveCurrency(currency)
            currencyDao.saveCurrency(currency1)

            val testObserver: Observer<List<Currency>> = mock()
            currencyDao.getCurrency().observeForever(testObserver)

            val listClass = ArrayList::class.java as Class<ArrayList<Currency>>
            val argumentCaptor = ArgumentCaptor.forClass(listClass)
            // 4
            verify(testObserver).onChanged(argumentCaptor.capture())
            // 5
            val capturedArgument = argumentCaptor.value
            System.out.println(capturedArgument.toString())
            assertTrue(capturedArgument.containsAll(listOf(currency, currency1)))
        }
    }

    @Test
    fun insertTimestamp() {
        val timestamp = Timestamp(timestamp = "23242424242")

        testCoroutineScope.launch {
            try {
                localRepository.saveTimestamp(timestamp)

                val timestampObserver: Observer<List<Timestamp>> = mock()
                localRepository.getTimestamp().observeForever(timestampObserver)

                val listClass = ArrayList::class.java as Class<ArrayList<Timestamp>>
                val argumentCaptor = ArgumentCaptor.forClass(listClass)

                verify(timestampObserver).onChanged(argumentCaptor.capture())

                val capturedArgument = argumentCaptor.value

                System.out.println(capturedArgument[0].timestamp + " :: ")

                assertTrue(capturedArgument[0].timestamp == timestamp.timestamp)
            } catch (e: Exception) {
                System.out.println(e.toString())
            }
        }
    }

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

}

Я использую Roboelectri c и я должен поместить allowMainThreadQueries () в объявление RoomInMemoryDatabase. Если не поставлю, тест не пройдёт. Что я неправильно реализовал?

Это мой класс Localrepository

fun getCurrency(): LiveData<List<Currency>> {
        return currencyDao.getCurrency()
    }

    fun getCurrency(timestamp: String): List<Currency> {
        return currencyDao.getCurrency(timestamp)
    }

    suspend fun saveCurrency(currency: Currency) {
        CoroutineScope(Dispatchers.IO).launch {
            currencyDao.saveCurrency(currency)
        }
    }

     fun getTimestamp(): LiveData<List<Timestamp>> {
        return timestampDao.getAllTimestamp()
    }

    suspend fun saveTimestamp(timestamp: Timestamp) {
        CoroutineScope(Dispatchers.IO).launch {
            timestampDao.saveTimestamp(timestamp)
        }
    }

    fun checkTimestamp(timestamp: String): LiveData<Timestamp> {
        return timestampDao.checkTimestamp(timestamp)
    }

    suspend fun getLatestTimestamp(): Timestamp? {
        return timestampDao.getLatestTimestamp()
    }

Пожалуйста, помогите мне решить проблему. Спасибо

...