Matchers Personalizados
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 esos dos mensajes quedará más clara con un ejemplo. Consideremos escribir un matcher de longitud para String, para verificar que una cadena tiene 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. Nota: no crees una instancia de MatcherResult directamente; en su lugar, usa la función de construcción MatcherResultBuilder que devolverá un tipo concreto apropiado para tu plataforma.
fun haveLength(length: Int) = Matcher<String> { value ->
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)
Haz clic para ver la diferencia
Al devolver un MatcherResult desde un matcher, si proporcionas un valor esperado y un valor real al MatcherResultBuilder, los mensajes de error incluirán un diff clicable en IntelliJ.
Variantes con Extensiones
Normalmente, queremos definir funciones de extensión que invoquen la función matcher por ti y devuelvan el valor original para encadenamiento. Así es como Kotest estructura los matchers incorporados, y Kotest adopta una estrategia de nomenclatura 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)