具有自己协程范围的单元测试类

时间:2019-10-07 02:22:04

标签: kotlin kotlin-coroutines

我有一堂课,看起来像

class Foo {
  private val scope = Job() + Dispatchers.IO
  val emissions = PublishSubject.create<Bar>()

  fun doSomething() {
    scope.launch {
      // Do a whole bunch of work...
      withContext(Dispatchers.Main) emissions.onNext(bar)
    }
  }
}

我正在尝试提出一种对它进行单元测试的方法。我试着使示波器可注入并编写类似

的内容
@Test fun testFoo() = runBlockingTest {
  Dispatchers.setMain(TestCoroutineDispatcher())
  val foo = Foo(this)
  foo.doSomething()
  foo.emissions.assertStuff()
}

但这似乎不起作用。该断言发生在doSomething()内部的协程完成之前。

我也尝试过使此调度程序可注入,提供了Dispatchers.Unconfined,但这也无济于事。这种方法有什么问题吗?

2 个答案:

答案 0 :(得分:0)

如果您能够公开公开API的工作,则可以尝试

class Foo {
  private val scope: CoroutineScope = CoroutineScope(Job() + Dispatchers.IO)
  val emissions = PublishSubject.create<Bar>()

  fun doSomething() = scope.launch {
    // Do a whole bunch of work...
    withContext(Dispatchers.Main) { emissions.onNext(bar) }
  }
}

class Test {
  private val testFoo = Foo()
  private val testObserver: TestObserver<Bar> = TestObserver.create()

  @BeforeEach
  fun setUp() {
    testFoo.emissions.subscribe(testObserver)
  }

  @Test fun testFoo() {
    runBlockingTest {
      Dispatchers.setMain(TestCoroutineDispatcher())
      testFoo.doSomething().join()
      testObserver.assertValue(bar)
    }
  }
}

答案 1 :(得分:0)

使用以下库可以很好地测试异步代码:Awaitilityor its kotlin extension

您将编写如下内容:

@Test fun testFoo() {

  val foo = Foo()

  foo.doSomething()

  await().atMost(5, MILLIS).until(/* your check like - foo.emissions.onNext(bar) */);
}