android – 如何运行协同程序作为单元测试的阻止?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了android – 如何运行协同程序作为单元测试的阻止?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3180字,纯文字阅读大概需要5分钟。
内容图文
![android – 如何运行协同程序作为单元测试的阻止?](/upload/InfoBanner/zyjiaocheng/812/ab7072481ae54ee383ec81103215588a.jpg)
我已经开始为我的MVP Android项目编写单元测试,但我的测试依赖于协同程序间歇性失败(通过记录和调试我已经确认验证有时会提前发生,当然会增加延迟修复)
我尝试用runBlocking包装,我从org.jetbrains.kotlinx:kotlinx-coroutines-test中发现了Dispatchers.setMain(mainThreadSurrogate),但尝试了这么多组合到目前为止还没有取得任何成功.
abstract class CoroutinePresenter : Presenter, CoroutineScope {
private lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onCreate() {
super.onCreate()
job = Job()
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
}
class MainPresenter @Inject constructor(private val getInfoUsecase: GetInfoUsecase) : CoroutinePresenter() {
lateinit var view: View
fun inject(view: View) {
this.view = view
}
override fun onResume() {
super.onResume()
refreshInfo()
}
fun refreshInfo() = launch {
view.showLoading()
view.showInfo(getInfoUsecase.getInfo())
view.hideLoading()
}
interface View {
fun showLoading()
fun hideLoading()
fun showInfo(info: Info)
}
}
class MainPresenterTest {
private val mainThreadSurrogate = newSingleThreadContext("Mocked UI thread")
private lateinit var presenter: MainPresenter
private lateinit var view: MainPresenter.View
val expectedInfo = Info()
@Before
fun setUp() {
Dispatchers.setMain(mainThreadSurrogate)
view = mock()
val mockInfoUseCase = mock<GetInfoUsecase> {
on { runBlocking { getInfo() } } doReturn expectedInfo
}
presenter = MainPresenter(mockInfoUseCase)
presenter.inject(view)
presenter.onCreate()
}
@Test
fun onResume_RefreshView() {
presenter.onResume()
verify(view).showLoading()
verify(view).showInfo(expectedInfo)
verify(view).hideLoading()
}
@After
fun tearDown() {
Dispatchers.resetMain()
mainThreadSurrogate.close()
}
}
我相信runBlocking块应该强制所有子coroutineScopes在同一个线程上运行,迫使它们在继续验证之前完成.
解决方法:
在CoroutinePresenter类中,您使用的是Dispatchers.Main.您应该能够在测试中更改它.尝试执行以下操作:
>将uiContext:CoroutineContext参数添加到演示者的构造函数中:
abstract class CoroutinePresenter(private val uiContext: CoroutineContext = Dispatchers.Main) : CoroutineScope {
private lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = uiContext + job
//...
}
class MainPresenter(private val getInfoUsecase: GetInfoUsecase,
private val uiContext: CoroutineContext = Dispatchers.Main
) : CoroutinePresenter(uiContext) { ... }
>更改MainPresenterTest类以注入另一个CoroutineContext:
class MainPresenterTest {
private lateinit var presenter: MainPresenter
@Mock
private lateinit var view: MainPresenter.View
@Mock
private lateinit var mockInfoUseCase: GetInfoUsecase
val expectedInfo = Info()
@Before
fun setUp() {
// Mockito has a very convenient way to inject mocks by using the @Mock annotation. To
// inject the mocks in the test the initMocks method needs to be called.
MockitoAnnotations.initMocks(this)
presenter = MainPresenter(mockInfoUseCase, Dispatchers.Unconfined) // here another CoroutineContext is injected
presenter.inject(view)
presenter.onCreate()
}
@Test
fun onResume_RefreshView() = runBlocking {
Mockito.`when`(mockInfoUseCase.getInfo()).thenReturn(expectedInfo)
presenter.onResume()
verify(view).showLoading()
verify(view).showInfo(expectedInfo)
verify(view).hideLoading()
}
}
内容总结
以上是互联网集市为您收集整理的android – 如何运行协同程序作为单元测试的阻止?全部内容,希望文章能够帮你解决android – 如何运行协同程序作为单元测试的阻止?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。