Ir al contenido principal
Versión: 5.2.x

Matchers Personalizados

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Es fácil definir tus propios matchers en Kotest.

Simplemente extiende la interfaz Matcher<T>, donde T es el tipo contra el que deseas hacer el matching. La interfaz Matcher especifica un método test que devuelve una instancia de MatcherResult.

interface Matcher<in T> {
fun test(value: T): MatcherResult
}

Este tipo MatcherResult define tres métodos: un booleano para indicar si la prueba pasó o falló, y dos mensajes de error.

interface MatcherResult {
fun passed(): Boolean
fun failureMessage(): String
fun negatedFailureMessage(): String
}

El primer mensaje de error es para el usuario cuando el predicado del matcher falla. Normalmente puedes incluir detalles sobre el valor esperado y el valor real, y cómo difirieron. El segundo mensaje de error es para el usuario cuando el predicado del matcher se evalúa como verdadero en modo negado. Aquí sueles indicar que esperabas que el predicado fallara.

La diferencia entre estos dos mensajes quedará más clara con un ejemplo. Consideremos escribir un matcher de longitud para cadenas, para verificar que una cadena tenga una longitud requerida. Querremos que nuestra sintaxis sea algo como str.shouldHaveLength(8).

Entonces el primer mensaje sería algo como "string had length 15 but we expected length 8". El segundo mensaje debería ser algo como "string should not have length 8".

Primero construimos nuestro tipo de matcher:

fun haveLength(length: Int) = Matcher<String> {
return MatcherResult(
value.length == length,
{ "string had length ${value.length} but we expected length $length" },
{ "string should not have length $length" },
)
}

Observa que envolvemos los mensajes de error en una llamada a función para no evaluarlos si no es necesario. Esto es importante para mensajes de error cuya generación requiera tiempo.

Este matcher puede pasarse luego a las funciones infijas should y shouldNot de la siguiente manera:

"hello foo" should haveLength(9)
"hello bar" shouldNot haveLength(3)

Variantes con Extensiones

Normalmente, queremos definir funciones de extensión que invoquen la función del matcher por ti y devuelvan el valor original para encadenamiento. Así es como Kotest estructura los matchers integrados, y Kotest adopta una estrategia de nombres shouldXYZ. Por ejemplo:

fun String.shouldHaveLength(length: Int): String {
this should haveLength(length)
return this
}

fun String.shouldNotHaveLength(length: Int): String {
this shouldNot haveLength(length)
return this
}

Luego podemos invocarlos así:

"hello foo".shouldHaveLength(9)
"hello bar".shouldNotHaveLength(3)