测试Kotlin控制台时要注入哪个Coroutine调度员
我有一个后端Springboot Kotlin应用程序,该应用具有一些简单的Coroutine代码,用于并行IO操作。 现在看起来像这样的
@Service
class AccountService(
private val client: ApiClient
private val coroutineDispatcher: CoroutineDispatcher
) {
fun getAccount(): AccountDTO {
return runBlocking(coroutineDispatcher) {
val foo = async {
client.getFoo() //some long operation
}
val bar = async {
client.getBar() //some other operation
}
AccountDTO(foo.await(), bar.await())
}
}
}
产品,我可以注入dispatchers.io
调度器,一切正常。但是,在测试时,我不需要多线程。我想注入dispatcher.main
,但它是针对Android应用的。另外,我想什么都不注入,让范围从父属继承并在主线程上运行,runblocking {}
在没有任何参数的情况下工作。但是我不知道该怎么做。我应该使用dispatchers.uncondined
吗?据我了解,除非我明确地旋转另一个线程,否则它将留在主线程上。
这里的标准做法是什么?
I have a back-end springboot Kotlin app that has some simple coroutine code for parallel IO operations. It looks something like this
@Service
class AccountService(
private val client: ApiClient
private val coroutineDispatcher: CoroutineDispatcher
) {
fun getAccount(): AccountDTO {
return runBlocking(coroutineDispatcher) {
val foo = async {
client.getFoo() //some long operation
}
val bar = async {
client.getBar() //some other operation
}
AccountDTO(foo.await(), bar.await())
}
}
}
Now in production I can inject let's say a Dispatchers.IO
dispatcher and everything works fine. However when testing I don't want multithreading. I want to inject Dispatcher.Main
but it's meant for android apps. Alternatively I'd like to inject nothing and let the scope inherit from the parent and run on the main thread, the way runBlocking{}
works without any arguments. But I can't figure out how to do that. Should I be using Dispatchers.Unconfined
? From what I understand it will stay on the main thread unless I spin up another thread myself explicitly.
What's the standard practice here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
但是,如果您控制了
getAccount()
在这里, >在此级别。如果您只是在项目中介绍Coroutines,那当然可以作为第一步,但是我鼓励您尽快继续上呼叫堆栈。这样,您将从上下文继承中受益,并避免将线程从其他Coroutines决定调用您的服务。现在,您可以使用
kotlinx-coroutines测试
进行测试,它们提供可以使用的测试调度程序,甚至可以控制虚拟时间和测试超时等。但是,请注意,请注意,这是由于虚拟时间,您无法将这种调度程序用于调用不属于虚拟时间的实际系统(例如某些外部服务,或者仅使用硬编码的非测试调度器)的代码。If you have control over
getAccount()
here, you should make this onesuspend
and avoidrunBlocking
at this level. If you're just introducing coroutines in the project, it's of course fine like this as a first step, but I would encourage you to keep going up the call stack soon. This way you'll benefit from context inheritance and avoid blocking threads from other coroutines if they decide to call your service.Now, you could use
kotlinx-coroutines-test
for your tests, they provide test dispatchers that you can use, which even allow you to control virtual time and test timeouts etc. Note, however, that due to the virtual time, you cannot use this kind of dispatcher for code that calls an actual system that's not part of virtual time (like some external service, or just a piece of code using a hardcoded non-test dispatcher).