Android测试的测试在测试使用RoomDatabase.withTransaction的挂起函数时冻结 [英] Android instrumented test freezes when it tests a suspend function that uses RoomDatabase.withTransaction

查看:87
本文介绍了Android测试的测试在测试使用RoomDatabase.withTransaction的挂起函数时冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试以下LocalDataSource函数,即 NameLocalData.methodThatFreezes 函数,但是它冻结了.我该如何解决?或如何以其他方式对其进行测试?

I'm trying to test the following LocalDataSource function, NameLocalData.methodThatFreezes function, but it freezes. How can I solve this? Or How can I test it in another way?

要测试的课程

class NameLocalData(private val roomDatabase: RoomDatabase) : NameLocalDataSource {

  override suspend fun methodThatFreezes(someParameter: Something): Something {
    roomDatabase.withTransaction {
      try {
        // calling room DAO methods here
      } catch(e: SQLiteConstraintException) {
        // ...
      }
      return something
    }
  }
}

测试课程

@MediumTest
@RunWith(AndroidJUnit4::class)
class NameLocalDataTest {
  private lateinit var nameLocalData: NameLocalData

  // creates a Room database in memory
  @get:Rule
  var roomDatabaseRule = RoomDatabaseRule()

  @get:Rule
  var instantTaskExecutorRule = InstantTaskExecutorRule()

  @Before
  fun setup() = runBlockingTest {
     initializesSomeData()
     nameLocalData = NameLocalData(roomDatabaseRule.db)
  }

 @Test
 fun methodThatFreezes() = runBlockingTest {
    nameLocalData.methodThatFreezes // test freezes
 }

 // ... others NameLocalDataTest tests where those functions been tested does not use
 // roomDatabase.withTransaction { } 
}

Gradle的文件配置

espresso_version = '3.2.0'
kotlin_coroutines_version = '1.3.3'
room_version = '2.2.5'

test_arch_core_testing = '2.1.0'
test_ext_junit_version = '1.1.1'
test_roboletric = '4.3.1'
test_runner_version = '1.2.0'

androidTestImplementation "androidx.arch.core:core-testing:$test_arch_core_testing"
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.test.ext:junit:$test_ext_junit_version"
androidTestImplementation "androidx.test:rules:$test_runner_version"
androidTestImplementation "androidx.test:runner:$test_runner_version"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"

推荐答案

上次我为Room数据库编写了一个测试,我只是简单地使用 runBlock ,它为我工作了...您能否看一下

Last time I wrote a test for Room database I just simply use runBlock and it worked for me... Could you take a look into this sample and check if it works for you as well?

行动!我错过了这一部分...(在同一示例中)我尝试过:

Ops! I missed this part... I tried this (in the same sample):

  1. 我使用 @Transaction
  2. 在我的DAO中定义了一个伪函数
  1. I defined a dummy function in my DAO using @Transaction

@Transaction
suspend fun quickInsert(book: Book) {
    save(book)
    delete(book)
}

  1. 我认为这是问题的关键.将 setTransactionExecutor 添加到数据库实例中.
  1. I think this is the key of the problem. Add setTransactionExecutor to your Database instantiation.

appDatabase = Room.inMemoryDatabaseBuilder(
    InstrumentationRegistry.getInstrumentation().context,
    AppDatabase::class.java
).setTransactionExecutor(Executors.newSingleThreadExecutor())
    .build()

  1. 最后,该测试使用 runBlocking

@Test
fun dummyTest() = runBlocking {
    val dao = appDatabase.bookDao();
    val id = dummyBook.id

    dao.quickInsert(dummyBook)

    val book = dao.bookById(id).first()
    assertNull(book)
}

请参见此问题.

这篇关于Android测试的测试在测试使用RoomDatabase.withTransaction的挂起函数时冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆