【发布时间】:2020-08-07 07:37:14
【问题描述】:
我正在尝试运行此 JUnit 4 测试以检查名为 dbState 的对象的正确 LiveData 值:
@Test
fun `saveNoteToDb - correct DB states`() {
val dbStatus = SUT.dbState?.testObserver()
val githubUser = GithubUser("", "")
`when`(insertUserUseCase.insert(githubUser))
.thenReturn(Completable.complete())
SUT.saveNoteToDb("", "")
Truth.assert_()
.that(dbStatus?.observedValues)
.isEqualTo(listOf(DB_SAVING, NOTE_SAVED))
}
但我得到了一个NullPointerException,Mockito 添加了一些不太有用的提示:
[MockitoHint] ProfileViewModelTest.saveNoteToDb - correct DB states (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.something.someapp.ui.profile.ProfileViewModelTest.saveNoteToDb - correct DB states(ProfileViewModelTest.kt:88)
[MockitoHint] ...args ok? -> at com.something.someapp.ui.profile.ProfileViewModel.saveNoteToDb(ProfileViewModel.kt:54)
java.lang.NullPointerException
at com.something.someapp.ui.profile.ProfileViewModel.saveNoteToDb(ProfileViewModel.kt:55)
at com.something.someapp.ui.profile.ProfileViewModelTest.saveNoteToDb - correct DB states(ProfileViewModelTest.kt:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
被测试的函数如下所示:
fun saveNoteToDb(userName: String, note: String) {
compositeDisposable += insertUserUseCase.insert(GithubUser(userName, note))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { _dbState.value = DB_SAVING }
.subscribeBy(
onComplete = { _dbState.value = NOTE_SAVED },
onError = {
_dbState.value = it.message?.let { msg -> DB_ERROR(msg) }
it.printStackTrace()
}
)
}
我是单元测试的新手,对此我完全感到困惑,特别是因为我做了一个类似的测试通过了。这将测试另一个名为 uiState 的 LiveData 对象
@Test
fun `fetchUserDetails - correct UI states`() {
val uiStatus = SUT.uiState?.testObserver()
`when`(searchUserUseCase.searchForUser("username")).thenReturn(Single.just(
SearchUserResponse()
))
SUT.fetchUserDetails("username")
Truth.assert_()
.that(uiStatus?.observedValues)
.isEqualTo(listOf(LOADING, SUCCESS))
}
这是之前成功测试的正在测试的功能:
fun fetchUserDetails(userName: String) {
compositeDisposable += searchUserUseCase.searchForUser(userName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { _uiState.value = LOADING }
.subscribeBy(
onSuccess = {
followers.set(it.followers.toString())
following.set(it.following.toString())
name.set(it.name)
location.set(it.location)
_uiState.value = SUCCESS
},
onError = { error ->
error.printStackTrace()
_uiState.value = error.message?.let {
ERROR(it)
}
}
)
}
testObserver 长这样,供参考:
open class TestObserver<T> : Observer<T> {
val observedValues = mutableListOf<T?>()
override fun onChanged(value: T?) {
observedValues.add(value)
}
}
fun <T> LiveData<T>.testObserver() = TestObserver<T>().also {
observeForever(it)
}
【问题讨论】:
标签: android unit-testing mockito junit4 android-livedata