Ir al contenido principal
Versión: 6.1

Should Be

[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 →

El principal matcher o aserción en Kotest es shouldBe. Este matcher se utiliza para verificar la igualdad entre un valor real y uno esperado. La sintaxis sigue el formato actual shouldBe expected. Por ejemplo:

val a = "samuel"
val b = a.take(3)
b shouldBe "sam"

Cuando dos valores no son iguales, Kotest mostrará un mensaje de error detallado que incluye un enlace de intellij <click to see difference> entre ambos valores. Por ejemplo:

Expected :world
Actual :hello
<Click to see difference>

Nota: puedes verificar que dos valores no son iguales usando shouldNotBe.

val a = "samuel"
val b = a.take(3)
b shouldNotBe "bob"
consejo

El matcher shouldBe puede combinarse con power assert para obtener mayor efectividad.

Internamente, Kotest utiliza el método equals pero añade lógica adicional para determinar igualdad en tipos donde la comparación simple de objetos no es adecuada. Por ejemplo, en JVM es conocido que Arrays con el mismo contenido no se considerarán iguales al usar el método equals. Otro ejemplo son primitivos de diferentes tipos aunque tengan el mismo valor.

Esta lógica está encapsulada en la typeclass Eq que Kotest usa internamente. También es posible definir tu propia lógica de igualdad para tipos implementando Eq y registrándola en Kotest.

Instancias personalizadas de Eq

Veamos un ejemplo de creación de una instancia personalizada de Eq para comparar objetos Foo. Primero, la definición de Foo:

data class Foo(val value: String)

Luego implementamos la typeclass Eq con la lógica de igualdad deseada, devolviendo un EqResult que puede ser Success o Failure:

Aquí estamos diciendo que si un Foo contiene el string hello y el otro contiene world, entonces son iguales. Para devolver un mensaje de error usamos AssertionErrorBuilder, un ayudante para construir el AssertionError concreto apropiado según la plataforma de ejecución.

object FooEq : Eq<Foo> {
override fun equals(actual: Foo, expected: Foo, context: EqContext): EqResult {
return if (actual.value == "hello" && expected.value == "world")
EqResult.Success
else EqResult.Failure {
AssertionErrorBuilder.create().withMessage("I don't like foo").build()
}
}
}
consejo

Si especificamos los valores esperado y real al constructor de errores, el enlace <click to see difference> se generará automáticamente.

Luego lo registramos en Kotest especificando el tipo al que aplica. Aquí usamos project config para configurarlo antes de ejecutar pruebas. También podríamos hacerlo a nivel de spec, pero considera que si ejecutas pruebas en paralelo el registro será no determinista.

class ProjectConfig : AbstractProjectConfig() {
override suspend fun beforeProject() {
DefaultEqResolver.register(Foo::class, FooEq)
}
}

Finalmente, podemos usar nuestra instancia personalizada de Eq en las pruebas simplemente usando shouldBe o shouldNotBe normalmente.

test("custom eq should be selected if both sides are the same type") {
Foo("hello") shouldBe Foo("world")
}
nota

Las instancias personalizadas de Eq solo se seleccionan si ambos lados de la llamada son exactamente del tipo especificado al registrarse. Los subtipos no se seleccionan automáticamente y deben registrarse por separado.