Der*_*son 1 android unit-testing kotlin kotlinx.coroutines
我正在使用协同程序在pull上进行异步调用以进行刷新,如下所示:
class DataFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {
// other functions here
override fun onRefresh() {
loadDataAsync()
}
private fun loadDataAsync() = async(UI) {
swipeRefreshLayout?.isRefreshing = true
progressLayout?.showContent()
val data = async(CommonPool) {
service?.getData() // suspending function
}.await()
when {
data == null -> showError()
data.isEmpty() -> progressLayout?.showEmpty(null, parentActivity?.getString(R.string.no_data), null)
else -> {
dataAdapter?.updateData(data)
dataAdapter?.notifyDataSetChanged()
progressLayout?.showContent()
}
}
swipeRefreshLayout?.isRefreshing = false
}
}
Run Code Online (Sandbox Code Playgroud)
当我把它放在一台设备上时,这里的一切都很好.我的错误,空白和数据状态都处理得很好,性能也很好.但是,我也试图用Spek进行单元测试.我的Spek测试看起来像这样:
@RunWith(JUnitPlatform::class)
class DataFragmentTest : Spek({
describe("The DataFragment") {
var uut: DataFragment? = null
beforeEachTest {
uut = DataFragment()
}
// test other functions
describe("when onRefresh") {
beforeEachTest {
uut?.swipeRefreshLayout = mock()
uut?.onRefresh()
}
it("sets swipeRefreshLayout.isRefreshing to true") {
verify(uut?.swipeRefreshLayout)?.isRefreshing = true // says no interaction with mock
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
测试失败,因为它说没有与uut?.swipeRefreshLayout模拟器的交互.经过一些实验,似乎这是因为我正在使用UI上下文async(UI).如果我让它只是一个常规的异步,我可以让测试通过,但然后应用程序崩溃,因为我正在修改UI线程之外的视图.
有什么想法可能会发生吗?此外,如果有人有任何更好的建议,这将使它更容易测试,我全都耳朵.
谢谢.
编辑:忘了提到我也尝试包装verify和uut?.onRefresh()中runBlocking,但我仍然没有成功.
如果你想让事情变得干净并考虑将来使用MVP架构,你应该明白CourutineContext是外部依赖,应该通过DI注入,或者传递给你的演示者.关于主题的更多细节.
您的问题的答案很简单,您应该只使用Unconfined CourutineContext进行测试.(更多)为简单起见创建一个对象,例如注入:
package com.example
object Injection {
val uiContext : CourutineContext = UI
val bgContext : CourutineContext = CommonPool
}
Run Code Online (Sandbox Code Playgroud)
并在测试包中创建绝对相同的对象,但更改为:
package com.example
object Injection {
val uiContext : CourutineContext = Unconfined
val bgContext : CourutineContext = Unconfined
}
Run Code Online (Sandbox Code Playgroud)
在你的课堂里,它会是这样的:
val data = async(Injection.bgContext) {service?.getData()}.await()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
582 次 |
| 最近记录: |