And*_*eky 5 testing android unit-testing android-room kotlin-coroutines
如何测试Room 的Transaction数据库操作?insertItineraries
错误
java.lang.IllegalStateException:此作业尚未完成
在 kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1188) 在 kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53) 在 kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45) ) 在 com.andigeeky.skyscannertest.db.ItineraryDaoTest.test 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 插入带腿的行程(ItineraryDaoTest.kt:44) )
行程道
@Dao
@OpenForTesting
interface ItineraryDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertLegEntities(legs: List<LegEntity>)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertItineraryEntities(itineraries: List<ItineraryEntity>)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertItineraryLeg(itineraryLegEntities: List<ItineraryLegEntity>)
@Transaction
suspend fun insertItineraries(
itineraries: List<ItineraryEntity>,
legs: List<LegEntity>,
itineraryLegEntities: List<ItineraryLegEntity>
){
insertItineraryEntities(itineraries)
insertLegEntities(legs)
insertItineraryLeg(itineraryLegEntities)
}
@Transaction
@Query("SELECT * FROM ItineraryEntity")
fun getItineraryWithLegs(): LiveData<List<ItineraryWithLegs>>
}
Run Code Online (Sandbox Code Playgroud)
行程Dao测试
@ExperimentalCoroutinesApi
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.P])
class ItineraryDaoTest : DbTest() {
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
@Captor
lateinit var captor: ArgumentCaptor<ArrayList<ItineraryWithLegs>>
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun `test insert itineraries with legs`() {
runBlockingTest {
val observer = mock<Observer<List<ItineraryWithLegs>>>()
val legs = TestUtil.createLegs(1)
val itineraries = TestUtil.createItineraries(1)
val itineraryLegs = TestUtil.createItineraryLegEntities(1)
skyScannerDatabase.itineraryDao().insertItineraries(itineraries, legs, itineraryLegs)
skyScannerDatabase.itineraryDao().getItineraryWithLegs().observeForever(observer)
captor.run {
verify(observer, times(1)).onChanged(capture())
assertEquals(itineraryLegs.size, value.size)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
数据库测试
@UseExperimental(ExperimentalCoroutinesApi::class)
abstract class DbTest : CoroutineTestBase() {
@Rule
@JvmField
val countingTaskExecutorRule = CountingTaskExecutorRule()
lateinit var skyScannerDatabase: SkyScannerDatabase
@Before
fun initDb() {
val app = ApplicationProvider.getApplicationContext<Context>()
skyScannerDatabase = Room.inMemoryDatabaseBuilder(app, SkyScannerDatabase::class.java)
.allowMainThreadQueries()
.setTransactionExecutor(Executors.newSingleThreadExecutor())
.build()
}
@After
fun closeDb() {
countingTaskExecutorRule.drainTasks(10, TimeUnit.SECONDS)
skyScannerDatabase.close()
}
}
Run Code Online (Sandbox Code Playgroud)
您应该在测试类之上使用@RunWith(AndroidJUnit4::class)注释来测试您的 DAO 。作为仪器测试运行(androidTest 文件夹下的测试类)。
@RunWith(AndroidJUnit4::class)
class YourTestClass {
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
lateinit var skyScannerDatabase: SkyScannerDatabase
@Before
fun initDb() {
val app = ApplicationProvider.getApplicationContext<Context>()
skyScannerDatabase = Room.inMemoryDatabaseBuilder(app, SkyScannerDatabase::class.java)
.allowMainThreadQueries()
.setTransactionExecutor(Executors.newSingleThreadExecutor())
.build()
}
@After
fun closeDb() {
skyScannerDatabase.close()
}
// ...
@Test
fun testMethod() = runBlockingTest {
skyScannerDatabase.itineraryDao().insertItineraries(...)
}
}
Run Code Online (Sandbox Code Playgroud)
您的 build.gradle 模块上应该有以下配置。
android {
// ...
defaultConfig {
// ...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// ...
}
}
// kotlin_coroutines_version = '1.3.3'
// test_arch_core_testing = '2.1.0'
// test_ext_junit_version = '1.1.1'
// test_runner_version = '1.2.0'
dependencies {
androidTestImplementation "androidx.arch.core:core-testing:$test_arch_core_testing"
androidTestImplementation "androidx.test.ext:junit:$test_ext_junit_version"
androidTestImplementation "androidx.test:runner:$test_runner_version"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
}
Run Code Online (Sandbox Code Playgroud)
看看这篇文章。
| 归档时间: |
|
| 查看次数: |
1838 次 |
| 最近记录: |