【问题标题】:Kotlin tests: conditionally assert throwing exceptions in parametrized testsKotlin 测试:有条件地断言在参数化测试中抛出异常
【发布时间】:2020-01-23 14:12:55
【问题描述】:

我想用 Kotlin 编写一个参数化测试。根据输入参数,被测试的函数应该抛出自定义异常,或者如果一切正常,它应该成功。我正在使用 JUnit Jupiter 5.3.2。

这是我现在的简化版本(实际上有多个输入参数)。它可以工作,但感觉有点难看,因为我需要包含两次测试的方法调用:

companion object {
      @JvmStatic
      fun paramSource(): Stream<Arguments> = Stream.of(
            Arguments.of(1, true),
            Arguments.of(2, false),
            Arguments.of(3, true)
      )
}

@ParameterizedTest
@MethodSource("paramSource")
open fun testMyServiceMethod(param: Int, shouldThrow: Boolean) {

      if (!shouldThrow) {
          // here the exception should not be thrown, so test will fail if it will be thrown
          myService.myMethodThrowingException(param)
      } else {
          assertThrows<MyCustomException>{
              myService.myMethodThrowingException(param)
          }
      }
}

有没有更好的方法?

【问题讨论】:

  • 1) 这篇文章应该移到 codereview.stackexchange,因为它是一个工作代码,你需要改进。 2)在单元测试中具有条件行为是一种不好的模式。如果您需要有两种情况,请定义两个参数化测试。 3) 单元测试不检查不抛出异常,这是一种不好的方法。

标签: testing kotlin syntax junit5


【解决方案1】:

你可以很容易地封装这个:

inline fun <reified E : Exception> assertThrowsIf(shouldThrow: Boolean, block: () -> Unit) {
    if (!shouldThrow) {
        block()
    } else {
        assertThrows<E>(block)
    }
}

用法:

@ParameterizedTest
@MethodSource("paramSource")
open fun testMyServiceMethod(param: Int, shouldThrow: Boolean) {
    assertThrowsIf<MyCustomException>(shouldThrow) {
        myService.myMethodThrowingException(param)
    }
}

【讨论】:

    【解决方案2】:

    正如 Neo 指出的那样,这不是一个好主意。在这种情况下,正确的解决方案是创建两个单独的测试 - 一个用于原始测试的每个案例。

    测试应尽可能少地包含逻辑。它们应该简单明了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 2014-05-10
      • 2020-12-21
      相关资源
      最近更新 更多