Inferir implícitamente el tipo de método fallido en JUnit 5

David Mbochi Njonge 20 junio 2023
  1. Crear un proyecto de Kotlin y agregar dependencias
  2. No hay suficiente información para inferir la variable de tipo V
  3. Inferir el Tipo del Método fail() Explícitamente
  4. Utilice el método fail() con expresiones lambda
  5. Inferir implícitamente el tipo del método fail()
  6. Conclusión
Inferir implícitamente el tipo de método fallido en JUnit 5

La prueba es un paso importante en el desarrollo de cualquier aplicación, ya que ayuda a detectar errores al principio de la etapa de desarrollo, mejora el rendimiento de la aplicación y reduce el costo de desarrollo.

Supongamos que la prueba es un proceso crítico en una aplicación. En ese caso, se recomienda utilizar el enfoque de desarrollo basado en pruebas (TDD), que comienza implementando cualquier característica con pruebas fallidas, seguido del código real que finalmente hace que la prueba pase.

Se pueden realizar diferentes tipos de pruebas en una aplicación, incluidas pruebas unitarias, pruebas de integración, pruebas funcionales y otras. Este tutorial enseñará cómo inferir implícitamente el tipo de método fail() utilizado en la etapa de pruebas unitarias con JUnit 5.

Crear un proyecto de Kotlin y agregar dependencias

Abra el entorno de desarrollo IntelliJ y seleccione Archivo > Nuevo > Proyecto. En la ventana que se abre, ingrese el proyecto Nombre como kotlin-testing, seleccione Kotlin en la sección Idioma y seleccione Gradle en la sección Build system.

Pulse el botón Crear para generar el proyecto.

Abra el archivo build.gradle y asegúrese de tener la dependencia junit-jupiter-api como se muestra a continuación. Esta dependencia nos proporciona las API que usamos para probar nuestro código.

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

Cree un archivo Main.kt en la carpeta src/main/kotlin y copie y pegue el siguiente código en el archivo.

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

En el código anterior, hemos creado una lista que contiene objetos estudiantes, y usaremos esta lista para realizar las pruebas.

No hay suficiente información para inferir la variable de tipo V

Cree un archivo Main.kt en la carpeta src/test/kotlin y copie y pegue el siguiente código en el archivo.

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

}

En este código, hemos creado una prueba con el nombre checkEmptyClass() que usa la lista que creamos en la sección anterior para verificar si está vacía. Si la lista no está vacía, llamamos al método fail() y pasamos un mensaje de error como argumento del método.

Tenga en cuenta que usamos el método estático fail() de la clase Assertions. El nombre completo de la clase es org.junit.jupiter.api.Assertions.

Al usar el método fail() de esta clase, el compilador muestra una advertencia con el mensaje No hay suficiente información para inferir la variable de tipo V porque el método es genérico y no hemos proporcionado ningún parámetro de tipo.

Inferir el Tipo del Método fail() Explícitamente

El enfoque más fácil que primero viene a la mente es proporcionar explícitamente los parámetros de tipo para apaciguar al compilador, como se muestra en el siguiente código.

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

}

Tenga en cuenta que la razón por la que usamos la declaración para apaciguar al compilador es que el tipo nunca se devuelve porque se lanza la excepción org.opentest4j.AssertionFailedError antes de llegar a la declaración de devolución.

En términos simples, proporcionamos un parámetro genérico que es inútil en nuestro código. La siguiente sección muestra cómo podemos llamar a este método sin proporcionar explícitamente los parámetros genéricos.

Ejecute esta prueba y asegúrese de que falla con el siguiente mensaje.

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

Utilice el método fail() con expresiones lambda

Comente el ejemplo anterior y copie y pegue el siguiente código en el archivo Main.kt en la carpeta src/test/kotlin.

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

}

En este ejemplo, hemos creado una prueba llamada findInvalidStudentIDCard() que itera a través de la lista de estudiantes, registra a los alumnos con un número de tarjeta válido y llama al método fail() si el número de tarjeta no es válido.

Hemos utilizado el método forEach() que acepta un parámetro y no devuelve ningún valor. Esto generalmente se conoce como un Consumidor.

Cuando trabajamos con expresiones lambda, no necesitamos inferir el tipo explícitamente, ya que el compilador puede inferir el tipo del Consumidor pasado al método.

En este código, el compilador no muestra ningún error de tiempo de compilación. Ejecute esta prueba y asegúrese de que la salida sea como se muestra a continuación.

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

Inferir implícitamente el tipo del método fail()

Comente el ejemplo anterior y copie y pegue el siguiente código en el archivo Main.kt en la carpeta src/test/kotlin.

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

}

En este ejemplo, hemos creado una prueba llamada checkClassSize() que cuenta el número de objetos de estudiante en la lista, y si el recuento es inferior a 5, llamamos al método fail() y pasamos un error. mensaje como argumento del método.

Tenga en cuenta que el método fail() en este ejemplo no es el método genérico de la clase Assertions. El método fail() de este ejemplo proviene del paquete org.junit.jupiter.api, que no es genérico.

Dado que el método no es genérico, no necesitamos pasar ningún parámetro. Ejecute esta prueba y asegúrese de que la salida sea como se muestra a continuación.

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

Conclusión

En este tutorial, hemos aprendido qué causa el error de tiempo de compilación cuando se usa el método fail(). Hemos aprendido cómo podemos inferir explícitamente el tipo de método para evitar esta advertencia.

En las últimas dos secciones, hemos aprendido cómo se infiere implícitamente el tipo cuando se usan expresiones lambda y cómo evitamos inferir el tipo usando un método que no es genérico.

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