Aleš Zrak
Aleš Zrak

Reputation: 673

Kotlin tests: conditionally assert throwing exceptions in parametrized tests

I'd like to write a parametrized test in Kotlin. Depending on input parameters, the tested function should throw custom exception or it should succeed if everything is ok. I'm using JUnit Jupiter 5.3.2.

This is simplified version of what I have now (there are multiple input parameters in fact). It works, but it feels a little ugly as I need to include the tested method call twice:

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)
          }
      }
}

Is there any better approach on this?

Upvotes: 0

Views: 699

Answers (2)

Aleš Zrak
Aleš Zrak

Reputation: 673

As Neo pointed out, this wasn't a good idea. Right solution in this case would be to create two separate tests - one for each case of the original test.

Tests should include as little logic as possible. They should be simple and straightforward.

Upvotes: 0

Alexey Romanov
Alexey Romanov

Reputation: 170723

You can easily encapsulate this:

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

Usage:

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

Upvotes: 1

Related Questions