Kotlin'de beklenen istisnaları test edin


91

Java'da, programcı JUnit test durumları için aşağıdaki gibi beklenen istisnaları belirleyebilir:

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

Bunu Kotlin'de nasıl yaparım? İki sözdizimi varyasyonunu denedim, ancak hiçbiri işe yaramadı:

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

Yanıtlar:


126

JUnit 4.12 için Java örneğinin Kotlin çevirisi :

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

Ancak, JUnit 4.13 tanıtıldı iki assertThrowsince-taneli istisna kapsamları için yöntemler:

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

Her iki assertThrowsyöntem de ek iddialar için beklenen istisnayı döndürür:

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

80

Kotlin'in bu tür bir birim testi yapmaya yardımcı olabilecek kendi test yardımcı paketi vardır.

Testiniz kullanımla çok anlamlı olabilir assertFailWith:

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

1
Bağlantınıza bir 404 gelirse, kotlin.testbaşka bir şeyle değiştirildi mi?
fredoverflow

@fredoverflow Hayır, değiştirilmez, ancak standart kitaplıklardan kaldırılır. Github kotlin deposunun bağlantısını güncelledim ancak maalesef belgelere herhangi bir bağlantı bulamıyorum. Her neyse, jar intelliJ'de kotlin-eklentisi tarafından gönderilir veya ağda bulabilir veya projenize maven / grandle bağımlılığı ekleyebilirsiniz.
Michele d'Amico

7
"org.jetbrains.kotlin: kotlin-test: $ kotlin_version"
derleyin

4
@ mac229 s / compile / testCompile /
Laurence Gonsalves

@AshishSharma: kotlinlang.org/api/latest/kotlin.test/kotlin.test/… assertFailWith istisnayı döndürün ve kendi iddianızı yazmak için kullanabilirsiniz.
Michele d'Amico

26

@Test(expected = ArithmeticException::class)Kotlin'in kütüphane yöntemlerinden birini kullanabilir, hatta daha iyisi failsWith().

Reified jenerikler ve bunun gibi yardımcı bir yöntem kullanarak bunu daha da kısaltabilirsiniz:

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

Ve ek açıklamayı kullanan örnek:

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

}

javaClass<T>()şimdi kullanımdan kaldırıldı. MyException::class.javaBunun yerine kullanın .
fasth

failsWith kullanımdan kaldırılmıştır, onun yerine assertFailsWith kullanılmalıdır.
gvlasov

15

Bunun için KotlinTest'i kullanabilirsiniz .

Testinizde, isteğe bağlı kodu bir shouldThrow bloğu ile sarmalayabilirsiniz:

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

doğru şekilde çalışmıyor gibi görünüyor. 1. shouldThrow <java.lang.AssertionError> {someMethod (). İsOK shouldBe true} - yeşil 2. shouldThrow <java.lang.AssertionError> {someMethod (). İsOK shouldBe false} - yeşil someMethod () throw "java .lang.AssertionError: gerektiği zaman "message" ve uygunsa nesneyi döndür Her iki durumda da, OK ve NOT olduğunda yeşil olmalıdır.
Ivan Trechyokas

Belki dokümanlara bir göz atın, 2016'daki cevabımdan
sksamuel

13

JUnit5 yerleşik kotlin desteğine sahiptir .

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
Bu benim tercih ettiğim cevap. Eğer alırsanız Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6assertThrows üzerine, emin build.gradle sahip oluncompileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
Büyük Kabak

11

Ayrıca jenerikleri kotlin.test paketi ile de kullanabilirsiniz:

import kotlin.test.assertFailsWith 

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

1

İstisna sınıfını ve ayrıca hata mesajının eşleşip eşleşmediğini doğrulayan uzantıyı onaylayın.

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

}

Örneğin:

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

1

AssertFailsWith () 'in değeri döndürdüğünden kimse bahsetmedi ve istisna niteliklerini kontrol edebilirsiniz:

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

0

Kluent kullanan başka bir sözdizimi sürümü :

@Test
fun `should throw ArithmeticException`() {
    invoking {
        val backHole = 1 / 0
    } `should throw` ArithmeticException::class
}

0

İlk adımlar, (expected = YourException::class)test açıklamasına eklemektir

@Test(expected = YourException::class)

İkinci adım, bu işlevi eklemektir

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

Sonunda böyle bir şeye sahip olacaksınız:

@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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.