【问题标题】:Testing exception thrown by Project Reactor onErrorMap测试 Project Reactor onErrorMap 抛出的异常
【发布时间】:2019-05-16 14:51:46
【问题描述】:

我正在尝试捕获由 Mono 引发的异常 (kotlin.Exception),然后捕获该异常,并引发新的异常 (MyException)。

下面的sn-p失败了……

class MyException : Exception("My Exception")
assertThrows<MyException> {
     Mono.fromCallable { throw Exception() }
         .onErrorMap { MyException() }
         .subscribe()
}

...出现以下错误:

org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> 
Expected :<com.company.project.service.SomeServiceTest$foobar$MyException> 
Actual   :<reactor.core.Exceptions.ErrorCallbackNotImplemented>

但是,以下通过

assertThrows<RuntimeException> {
    Mono.fromCallable { throw Exception() }
        .onErrorMap { RuntimeException() }
        .subscribe()
}

我不确定为什么。除了我使用的是自定义异常,我看不出有什么区别。

我也尝试过使用block(),结果相似:

class MyException : Exception("My Exception")
assertThrows<MyException> {
    Mono.fromCallable { throw Exception() }
            .onErrorMap { MyException() }
            .block()
}

不同的例外:

org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> 
Expected :<com.company.project.service.SomeServiceTest$foobar$MyException> 
Actual   :<reactor.core.Exceptions.ReactiveException>

【问题讨论】:

  • assertThrows&lt;RuntimeException&gt; 通过是因为 ErrorCallbackNotImplemented 扩展了 RuntimeException。我认为,如果您进一步查看调试器,那里抛出的异常仍然是ErrorCallbackNotImplemented。我 - 认为 - 你想要做的是在你的 .subscribe 方法中添加一个错误子句,在那里你可能会得到你期望的异常,如果你愿意,你可以重新抛出它。
  • 谢谢@jolo,你是对的——测试通过是一个“红鲱鱼”,正如你正确地注意到ErrorCallbackNotImplemented 扩展RuntimeException。我认为这里的问题是.subscribe() 不会阻塞并返回异常本身,这需要通过像你说的那样传递回调函数来实现。所以,我认为使用.block() 更合适。这有点奇怪,它返回ReactiveException,而不是MyException
  • 很高兴能帮上忙!

标签: kotlin project-reactor


【解决方案1】:

如果您想测试 Publisher (Mono/Flux),您应该使用 StepVerifier。不要忘记,当你使用 subscribe 方法时,它不会阻塞线程。这可能导致您的测试有时可以通过,有时却不能通过,因为测试(主)线程可以在您的测试流(单声道)完成之前终止。

class MyException : Exception("My Exception")

@Test
fun `correct exception mapping`() {
    val theMonoWeWantToTest = Mono
        .fromCallable { throw Exception() }
        .onErrorMap { MyException() }

    theMonoWeWantToTest
        .test() // Kotlin's extension function for Reactor's StepVerifier
        .expectError(MyException::class.java)
        .verify()
}

【讨论】:

    【解决方案2】:

    assertThrows&lt;RuntimeException&gt; 通过是因为 ErrorCallbackNotImplemented 扩展了 RuntimeException。我想如果你在调试器中进一步观察,那里抛出的异常仍然是ErrorCallbackNotImplemented。我 - 认为 - 你想要做的是在你的 .subscribe 方法中添加一个错误子句,在那里你可能会得到你期望的异常,如果你愿意,你可以重新抛出它。

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 2014-05-10
      • 2019-05-04
      • 1970-01-01
      • 2015-06-04
      • 2013-09-08
      • 2011-01-05
      • 2018-03-31
      • 2020-12-21
      相关资源
      最近更新 更多