间谍 Mockito 与协程

huangapple go评论109阅读模式
英文:

spy Mockito with Coroutines

问题

以下是您提供的内容的翻译部分:

  1. 我有一个名为 ViewModel 的类
  2. 当变量 shouldCheck 改变时会调用函数 open
  3. class ViewModel {
  4. val shouldCheck = MutableLiveData<Boolean>()
  5. val check by lazy {
  6. shouldCheck.switchMap {
  7. liveData(Dispatchers.IO) {
  8. open()
  9. emit(true)
  10. }
  11. }
  12. }
  13. fun open(){
  14. println("我是开放的")
  15. }
  16. }
  17. 我创建了一个简单的测试但验证 open 函数失败了
  18. @ExperimentalCoroutinesApi
  19. class CoroutineTestRule(private val dispatcher: CoroutineDispatcher = TestCoroutineDispatcher()) : TestWatcher() {
  20. override fun starting(description: Description?) {
  21. super.starting(description)
  22. Dispatchers.setMain(dispatcher)
  23. }
  24. override fun finished(description: Description?) {
  25. super.finished(description)
  26. Dispatchers.resetMain()
  27. }
  28. }
  29. @get:Rule
  30. val coroutineScope = CoroutineTestRule()
  31. @Before
  32. fun setUp() {
  33. viewModel = spy(ViewModel())
  34. }
  35. @Test
  36. fun checkTest() = runBlocking {
  37. // 观察
  38. viewModel.check.observeForever {
  39. // ...
  40. }
  41. // 动作
  42. viewModel.shouldCheck.value = true
  43. // 预期
  44. verify(viewModel, times(1)).open()
  45. }
  46. 在调试模式下我检查了一下函数 open 被调用了并打印出 "我是开放的"但我遇到了这个错误
  47. Wanted but not invoked:
  48. viewModel.open();
  49. However, there were exactly 2 interactions with this mock:
  50. 如果我移除 switchMap `liveData(Dispatchers.IO)`测试就会通过但我需要保留它
英文:

I have a class with the name ViewModel.

When the variable shouldCheck change, the function open is called.

  1. class ViewModel {
  2. val shouldCheck = MutableLiveData&lt;Boolean&gt;()
  3. val check by lazy {
  4. shouldCheck.switchMap {
  5. liveData(Dispatchers.IO) {
  6. open()
  7. emit(true)
  8. }
  9. }
  10. }
  11. fun open(){
  12. println(&quot;I am open&quot;)
  13. }
  14. }

I create a simple test. but verify function open is failed

  1. @ExperimentalCoroutinesApi
  2. class CoroutineTestRule(private val dispatcher: CoroutineDispatcher = TestCoroutineDispatcher()) : TestWatcher() {
  3. override fun starting(description: Description?) {
  4. super.starting(description)
  5. Dispatchers.setMain(dispatcher)
  6. }
  7. override fun finished(description: Description?) {
  8. super.finished(description)
  9. Dispatchers.resetMain()
  10. }
  11. }
  12. @get:Rule
  13. val coroutineScope = CoroutineTestRule()
  14. @Before
  15. fun setUp() {
  16. viewModel = spy(ViewModel())
  17. }
  18. @Test
  19. fun checkTest() = runBlocking {
  20. // observe
  21. viewModel.check.observeForever {
  22. // ...
  23. }
  24. // Action
  25. viewModel.shouldCheck.value = true
  26. // Expected
  27. verify(viewModel, times(1)).open()
  28. }

in debug mode, I checked that and function open is called.and print &quot;I am open&quot;, but I have this error.

  1. Wanted but not invoked:
  2. viewModel.open();
  3. However, there were exactly 2 interactions with this mock:

if I remove switchMap and liveData(Dispatchers.IO) test passed.
but I need it there.

答案1

得分: 0

根据谷歌:

我的建议是像这样注入调度程序:

  1. class MyViewModel(private val ioDispatcher: CoroutineDispatcher)

在测试中使用 TestCoroutineDispatcher,这可能会有所帮助。

英文:

According to Google:

间谍 Mockito 与协程

My advice would be to inject the dispatcher like this:

  1. class MyViewModel(private val ioDispatcher: CoroutineDispatcher)

And use the TestCoroutineDispatcher within your tests, this might help

huangapple
  • 本文由 发表于 2020年10月19日 23:54:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64430931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定