Leiten Sie implizit die Type of Fail-Methode in JUnit 5 ab

David Mbochi Njonge 20 Juni 2023
  1. Erstellen Sie ein Kotlin-Projekt und fügen Sie Abhängigkeiten hinzu
  2. Nicht genügend Informationen, um Typvariable V abzuleiten
  3. Leiten Sie den Typ der fail()-Methode explizit ab
  4. Verwenden Sie die fail()-Methode mit Lambda-Ausdrücken
  5. Implizites Ableiten des Typs der fail()-Methode
  6. Abschluss
Leiten Sie implizit die Type of Fail-Methode in JUnit 5 ab

Das Testen ist ein wichtiger Schritt in der Entwicklung jeder Anwendung, da es dabei hilft, Fehler frühzeitig in der Entwicklungsphase zu erkennen, die Leistung der Anwendung zu verbessern und die Entwicklungskosten zu senken.

Angenommen, das Testen ist ein kritischer Prozess in einer Anwendung. In diesem Fall wird empfohlen, den Ansatz der testgetriebenen Entwicklung (TDD) zu verwenden, der mit der Implementierung eines beliebigen Features mit fehlgeschlagenen Tests beginnt, gefolgt vom eigentlichen Code, der den Test schließlich erfolgreich macht.

In einer Anwendung können verschiedene Arten von Tests durchgeführt werden, darunter Komponententests, Integrationstests, Funktionstests und andere. In diesem Tutorial lernen Sie, wie Sie implizit den Typ der fail()-Methode ableiten, die in der Unit-Testphase mit JUnit 5 verwendet wird.

Erstellen Sie ein Kotlin-Projekt und fügen Sie Abhängigkeiten hinzu

Öffnen Sie die IntelliJ-Entwicklungsumgebung und wählen Sie Datei > Neu > Projekt. Geben Sie im sich öffnenden Fenster den Projektnamen Name als kotlin-testing ein, wählen Sie Kotlin im Abschnitt Sprache und wählen Sie Gradle im Abschnitt System erstellen.

Drücken Sie die Schaltfläche Erstellen, um das Projekt zu erstellen.

Öffnen Sie die Datei build.gradle und stellen Sie sicher, dass Sie die Abhängigkeit junit-jupiter-api haben, wie unten gezeigt. Diese Abhängigkeit stellt uns die APIs zur Verfügung, die wir zum Testen unseres Codes verwenden.

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
    testImplementation 'org.jetbrains.kotlin:kotlin-test'
}

Erstellen Sie eine Main.kt-Datei im Ordner src/main/kotlin und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

class Student(
    var id: Int,
    var studentName: String?,
    var studentIDCard: String?){

    override fun toString(): String {
        return "student name: $studentName, ID card: $studentIDCard"
    }
}

fun getStudents(): List<Student>{
    return listOf(
        Student(1,"john doe","CSO12022"),
        Student(2,"mary public","CS022022"),
        Student(3,"elon mask","S032022")
    );
}

Im obigen Code haben wir eine Liste erstellt, die student-Objekte enthält, und wir werden diese Liste zum Testen verwenden.

Nicht genügend Informationen, um Typvariable V abzuleiten

Erstellen Sie eine Main.kt-Datei im Ordner src/test/kotlin und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.fail

class TestStudents{
    private val students: List<Student> = getStudents();

     @Test
    fun checkEmptyClass(){
        if (students.isNotEmpty()){
            fail("The class is not empty")
        }
    }

}

In diesem Code haben wir einen Test mit dem Namen checkEmptyClass() erstellt, der die Liste, die wir im vorherigen Abschnitt erstellt haben, verwendet, um zu prüfen, ob sie leer ist. Wenn die Liste nicht leer ist, rufen wir die Methode fail() auf und übergeben eine Fehlermeldung als Argument der Methode.

Beachten Sie, dass wir die statische Methode fail() der Klasse Assertions verwenden. Der vollqualifizierte Name der Klasse lautet org.junit.jupiter.api.Assertions.

Bei Verwendung der Methode fail() aus dieser Klasse zeigt der Compiler eine Warnung mit der Meldung Not enough information to infer type variable V, da die Methode generisch ist und wir keine Typparameter angegeben haben.

Leiten Sie den Typ der fail()-Methode explizit ab

Der einfachste Ansatz, der einem in den Sinn kommt, besteht darin, die Typparameter explizit bereitzustellen, um den Compiler zu beruhigen, wie im folgenden Code gezeigt.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.fail

class TestStudents{
    private val students: List<Student> = getStudents();

      @Test
    fun checkEmptyClass(){
        if (students.isNotEmpty()){
            fail<String>("The class is not empty")
        }
    }

}

Beachten Sie, dass der Grund, warum wir die Anweisung verwendet haben, um den Compiler zu beruhigen, darin besteht, dass der Typ nie zurückgegeben wird, da die Ausnahme org.opentest4j.AssertionFailedError ausgelöst wird, bevor die return-Anweisung erreicht wird.

Einfach ausgedrückt stellen wir einen generischen Parameter bereit, der in unserem Code nutzlos ist. Der nächste Abschnitt zeigt, wie wir diese Methode aufrufen können, ohne die generischen Parameter explizit bereitzustellen.

Führen Sie diesen Test aus und stellen Sie sicher, dass er mit der folgenden Meldung fehlschlägt.

The class is not empty
org.opentest4j.AssertionFailedError: The class is not empty

Verwenden Sie die fail()-Methode mit Lambda-Ausdrücken

Kommentieren Sie das obige Beispiel und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei Main.kt im Ordner src/test/kotlin ein.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.fail

class TestStudents{
    private val students: List<Student> = getStudents();

    @Test
    fun findInvalidStudentIDCard(){
       students.forEach { student: Student ->
           if (student.studentIDCard?.startsWith("CS") == true){
               println(student)
           }else{
               fail("$student has an invalid id");
           }
       }
    }

}

In diesem Beispiel haben wir einen Test namens findInvalidStudentIDCard() erstellt, der die Liste student durchläuft, die Studenten mit einer gültigen Kartennummer protokolliert und die Methode fail() aufruft, wenn die Kartennummer ungültig ist.

Wir haben die Methode forEach() verwendet, die einen Parameter akzeptiert und keinen Wert zurückgibt. Dieser wird üblicherweise als Verbraucher bezeichnet.

Bei der Arbeit mit Lambda-Ausdrücken müssen wir den Typ nicht explizit ableiten, da der Compiler den Typ aus dem an die Methode übergebenen Consumer ableiten kann.

In diesem Code zeigt der Compiler keine Kompilierzeitfehler an. Führen Sie diesen Test durch und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

student name: john doe, ID card: CSO12022
student name: mary public, ID card: CS022022

student name: elon mask, ID card: S032022 has an invalid id
org.opentest4j.AssertionFailedError: student name: elon mask, ID card: S032022 has an invalid id

Implizites Ableiten des Typs der fail()-Methode

Kommentieren Sie das obige Beispiel und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei Main.kt im Ordner src/test/kotlin ein.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.fail

class TestStudents{
    private val students: List<Student> = getStudents();

    @Test
    fun checkClassSize(){
        if (students.count() < 5){
            fail("The class is not full")
        }
    }

}

In diesem Beispiel haben wir einen Test namens checkClassSize() erstellt, der die Anzahl der Schülerobjekte in der Liste zählt, und wenn die Anzahl kleiner als 5 ist, rufen wir die Methode fail() auf und übergeben einen Fehler message als Argument der Methode.

Beachten Sie, dass die Methode fail() in diesem Beispiel nicht die generische Methode der Klasse Assertions ist. Die Methode fail() in diesem Beispiel stammt aus dem Paket org.junit.jupiter.api, das nicht generisch ist.

Da die Methode nicht generisch ist, müssen wir keine Parameter übergeben. Führen Sie diesen Test durch und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

The class is not full
org.opentest4j.AssertionFailedError: The class is not full

Abschluss

In diesem Tutorial haben wir gelernt, was den Kompilierzeitfehler verursacht, wenn die Methode fail() verwendet wird. Wir haben gelernt, wie wir explizit auf den Typ der Methode schließen können, um diese Warnung zu vermeiden.

In den letzten beiden Abschnitten haben wir gelernt, wie der Typ implizit abgeleitet wird, wenn Lambda-Ausdrücke verwendet werden, und wie wir vermeiden, den Typ abzuleiten, indem wir eine nicht generische Methode verwenden.

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub