一段时间以来,我们一直在使用 Kotlin,我们目前关注的一件事是使用协程来处理我们想要异步运行的操作。
虽然示例用法很清楚并且有效,但我在我们的架构中以干净的方式集成它时遇到了一些问题。在查看以领域为中心的类的方法实现时,想法是它易于阅读,并且异步功能的“噪音”尽可能少。我知道我不能有异步,没有实际使用它。所以写这样的东西就是我想要的:
val data = someService.getData().await()
// work with data
但这是我想防止的:
launch(UI) {
val data
val job = async(CommonPool) {
data = someService.getData()
}
job.await()
// work with data
}
那,我想为这些以领域为中心的课程搭配实用的单元测试,但我真的无法让它发挥作用。让我们看一个例子:
// Some dependency doing heavy work
class ApiClient {
suspend fun doExpensiveOperation(): String {
delay(1000)
return "Expensive Result Set"
}
}
// Presenter Class
class Presenter(private val apiClient: ApiClient,
private val view: TextView) {
private lateinit var data: String
fun start() {
log("Starting Presenter")
runBlocking {
log("Fetching necessary data")
data = apiClient.doExpensiveOperation()
log("Received necessary data")
}
workWithData()
log("Started Presenter")
}
fun workWithData() {
log(data)
}
private fun log(text: String) {
view.append(text+"\n")
}
}
// In an Activity
val presenter = Presenter(ApiClient(), someTextView)
presenter.start()
这有效(截图:https ://imgur.com/a/xG9Xw )。现在让我们看看测试。
class PresenterTest {
// ... Declared fields
@Before
fun setUp() {
// Init mocks (apiClient, textView)
MockitoAnnotations.initMocks(this)
// Set mock responses
runBlocking {
given(apiClient.doExpensiveOperation()).willReturn("Some Value")
}
presenter = Presenter(apiClient, textView)
}
@Test
@Throws(Exception::class)
fun testThat_whenPresenterStarts_expectedResultShows() {
// When
presenter.start()
// Then
Mockito.verify(textView).text = "Some Value\n"
}
}
现在这个测试不太理想,但无论如何,它甚至无法验证事情是否按预期工作,因为没有初始化 lateinit var 数据。现在归根结底,我们的领域类的美观和可读性就是我想走多远,我有一些我很满意的实际工作示例。但是让我的测试工作似乎具有挑战性。
现在网上有一些关于这类东西的不同文章,但对我来说没有任何效果。这(https://medium.com/@tonyowen/android-kotlin-coroutines-unit-test-16e984ba35b4)看起来很有趣,但我不喜欢调用类为演示者启动上下文的想法,因为在turn 具有执行一些异步工作的依赖项。虽然作为一个抽象的想法,我喜欢“嘿,演示者,无论你做什么,就 UI 上下文向我报告”的想法,但它更像是一种使事情正常进行的修复,导致对不同对象的异步功能的共同关注.
无论如何,我的问题:远离简短的示例,是否有人对如何将协程集成到更大的架构中以及工作单元测试有任何指示?我也很愿意接受那些让我改变看待事物的方式的论点,因为它在不同的层面上具有说服力,而不是“如果你想让事情发挥作用,你就必须牺牲。”。这个问题不仅仅是让示例工作,因为这只是一个孤立的示例,而我正在寻找一个大项目中真正可靠的集成。
期待您的输入。提前致谢。