Kotlin에서 예상되는 예외 테스트


90

Java에서 프로그래머는 다음과 같이 JUnit 테스트 케이스에 대해 예상되는 예외를 지정할 수 있습니다.

@Test(expected = ArithmeticException.class)
public void omg()
{
    int blackHole = 1 / 0;
}

Kotlin에서 어떻게해야하나요? 두 가지 구문 변형을 시도했지만 모두 작동하지 않았습니다.

import org.junit.Test

// ...

@Test(expected = ArithmeticException) fun omg()
    Please specify constructor invocation;
    classifier 'ArithmeticException' does not have a companion object

@Test(expected = ArithmeticException.class) fun omg()
                            name expected ^
                                            ^ expected ')'

답변:


125

JUnit 4.12 용 Java 예제의 Kotlin 번역 은 다음과 같습니다.

@Test(expected = ArithmeticException::class)
fun omg() {
    val blackHole = 1 / 0
}

그러나 JUnit 4.13 assertThrows 세분화 된 예외 범위를위한 두 가지 방법을 도입했습니다 .

@Test
fun omg() {
    // ...
    assertThrows(ArithmeticException::class.java) {
        val blackHole = 1 / 0
    }
    // ...
}

assertThrows메서드 모두 추가 어설 션에 대해 예상되는 예외를 반환합니다.

@Test
fun omg() {
    // ...
    val exception = assertThrows(ArithmeticException::class.java) {
        val blackHole = 1 / 0
    }
    assertEquals("/ by zero", exception.message)
    // ...
}

79

Kotlin에는 이러한 종류 의 단위 테스트 를 수행하는 데 도움이 될 수 있는 자체 테스트 도우미 패키지 가 있습니다.

테스트는 다음과 같이 사용하여 매우 표현력이 있습니다 assertFailWith.

@Test
fun test_arithmethic() {
    assertFailsWith<ArithmeticException> {
        omg()
    }
}

1
링크에 404가 표시되면 kotlin.test다른 것으로 대체 되었습니까?
fredoverflow

@fredoverflow 아니오, 대체되지 않고 표준 라이브러리에서 제거되었습니다. github kotlin 저장소에 대한 링크를 업데이트했지만 불행히도 문서에 대한 링크를 찾을 수 없습니다. 어쨌든 jar는 intelliJ의 kotlin-plugin에 의해 배송되거나 인터넷에서 찾거나 프로젝트에 maven / grandle 종속성을 추가 할 수 있습니다.
Michele d' Amico

7
컴파일 "org.jetbrains.kotlin : kotlin-test : $ kotlin_version"
mac229

4
@ mac229 S / 컴파일 / testCompile /
로렌스 Gonsalves

@AshishSharma : kotlinlang.org/api/latest/kotlin.test/kotlin.test/… assertFailWith 예외를 반환하고이를 사용하여 자신의 assert를 작성할 수 있습니다.
Michele d' Amico

26

@Test(expected = ArithmeticException::class).NET과 같은 Kotlin의 라이브러리 메소드 중 하나를 사용 하거나 더 나은 방법을 사용할 수 있습니다 failsWith().

수정 된 제네릭과 다음과 같은 도우미 메서드를 사용하여 더 짧게 만들 수 있습니다.

inline fun <reified T : Throwable> failsWithX(noinline block: () -> Any) {
    kotlin.test.failsWith(javaClass<T>(), block)
}

그리고 주석을 사용한 예 :

@Test(expected = ArithmeticException::class)
fun omg() {

}

javaClass<T>()현재 사용되지 않습니다. MyException::class.java대신 사용하십시오 .
fasth

failsWith는 더 이상 사용되지 않으며 대신 assertFailsWith를 사용해야합니다.
gvlasov

15

이를 위해 KotlinTest 를 사용할 수 있습니다 .

테스트에서 shouldThrow 블록으로 임의 코드를 래핑 할 수 있습니다.

shouldThrow<ArithmeticException> {
  // code in here that you expect to throw a ArithmeticException
}

적절한 방식으로 작동하지 않는 것 같습니다. 나는 체크 1. shouldThrow <java.lang.AssertionError> {someMethod (). isOK shouldBe true}-green 2. shouldThrow <java.lang.AssertionError> {someMethod (). isOK shouldBe false}-green someMethod () throw "java .lang.AssertionError : message "가 표시되고 확인되면 객체를 반환합니다. 두 경우 모두 shouldThrow는 정상일 때와 그렇지 않을 때 녹색입니다.
Ivan Trechyokas 2018

문서를 살펴보면 2016 년 제 답변 이후로 변경되었을 수 있습니다. github.com/kotlintest/kotlintest/blob/master/doc/…
sksamuel

13

JUnit5에는 kotlin 지원이 내장되어 있습니다.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class MyTests {
    @Test
    fun `division by zero -- should throw ArithmeticException`() {
        assertThrows<ArithmeticException> {  1 / 0 }
    }
}

3
이것이 제가 선호하는 대답입니다. 당신이 얻을 경우 Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6assertThrows에서 확인하십시오 build.gradle을 가지고 있는지 확인compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
큰 호박

11

kotlin.test 패키지와 함께 제네릭을 사용할 수도 있습니다.

import kotlin.test.assertFailsWith 

@Test
fun testFunction() {
    assertFailsWith<MyException> {
         // The code that will throw MyException
    }
}

1

예외 클래스와 오류 메시지가 일치하는지 확인하는 Assert 확장입니다.

inline fun <reified T : Exception> assertThrows(runnable: () -> Any?, message: String?) {
try {
    runnable.invoke()
} catch (e: Throwable) {
    if (e is T) {
        message?.let {
            Assert.assertEquals(it, "${e.message}")
        }
        return
    }
    Assert.fail("expected ${T::class.qualifiedName} but caught " +
            "${e::class.qualifiedName} instead")
}
Assert.fail("expected ${T::class.qualifiedName}")

}

예를 들면 :

assertThrows<IllegalStateException>({
        throw IllegalStateException("fake error message")
    }, "fake error message")

1

assertFailsWith ()가 값을 반환한다고 언급 한 사람은 아무도 없으며 예외 속성을 확인할 수 있습니다.

@Test
fun `my test`() {
        val exception = assertFailsWith<MyException> {method()}
        assertThat(exception.message, equalTo("oops!"))
    }
}


0

올바른 단계는 (expected = YourException::class)테스트 주석 을 추가하는 것 입니다.

@Test(expected = YourException::class)

두 번째 단계는이 기능을 추가하는 것입니다.

private fun throwException(): Boolean = throw YourException()

마지막으로 다음과 같은 내용이 표시됩니다.

@Test(expected = ArithmeticException::class)
fun `get query error from assets`() {
    //Given
    val error = "ArithmeticException"

    //When
    throwException()
    val result =  omg()

    //Then
    Assert.assertEquals(result, error)
}
private fun throwException(): Boolean = throw ArithmeticException()

0

org.junit.jupiter.api.Assertions.kt

/**
 * Example usage:
 * ```kotlin
 * val exception = assertThrows<IllegalArgumentException>("Should throw an Exception") {
 *     throw IllegalArgumentException("Talk to a duck")
 * }
 * assertEquals("Talk to a duck", exception.message)
 * ```
 * @see Assertions.assertThrows
 */
inline fun <reified T : Throwable> assertThrows(message: String, noinline executable: () -> Unit): T =
        assertThrows({ message }, executable)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.