Ir al contenido principal
Versión: 5.3.x

Extensiones del sistema

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

Extensiones del sistema

En ocasiones, tu código puede utilizar funcionalidades directamente de la JVM que son difíciles de simular. Con las Extensiones del Sistema de Kotest, estas dificultades se simplifican para simular y mockear, permitiendo probar tu código correctamente. Tras modificar el sistema mediante estas extensiones, el estado original se restaurará automáticamente.

precaución

Este código es sensible a concurrencia. Según la especificación de la JVM, solo puede existir una instancia de estas extensiones en ejecución (ej: solo puede existir un mapa de entorno). Si intentas ejecutar múltiples instancias simultáneamente, el resultado será impredecible.

Entorno del sistema

Con la Extensión de Entorno del Sistema puedes simular el comportamiento del entorno del sistema. Es decir, lo que obtendrías mediante System.getenv().

Kotest ofrece funciones de extensión que proporcionan un entorno del sistema en un ámbito específico:

withEnvironment("FooKey", "BarValue") {
System.getenv("FooKey") shouldBe "BarValue" // System environment overridden!
}
información

Para usar withEnvironment con JDK17, debes añadir --add-opens=java.base/java.util=ALL-UNNAMED a los argumentos de la JVM que ejecuta las pruebas.

Si ejecutas pruebas con Gradle, añade esto en tu build.gradle.kts:

tasks.withType<Test>().configureEach {
jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED")
}

También puedes usar múltiples valores en esta extensión mediante un mapa o lista de pares.

withEnvironment(mapOf("FooKey" to "BarValue", "BarKey" to "FooValue")) {
// Use FooKey and BarKey
}

Estas funciones añadirán claves y valores si no existen actualmente en el entorno, y sobrescribirán los existentes. Las claves no modificadas por la función permanecerán intactas.

Como alternativa a las funciones de extensión, puedes usar los listeners proporcionados para aplicar estas funcionalidades en un ámbito más amplio. Existen opciones a nivel de Spec/prueba individual y a nivel de proyecto.


class MyTest : FreeSpec() {

override fun listeners() = listOf(SystemEnvironmentTestListener("foo", "bar"))

init {
"MyTest" {
System.getenv("foo") shouldBe "bar"
}
}

}


class ProjectConfig : AbstractProjectConfig() {

override fun listeners(): List<TestListener> = listOf(SystemEnvironmentProjectListener("foo", "bar"))

}

Extensión de propiedades del sistema

De manera similar a las extensiones de entorno, puedes sobrescribir las propiedades del sistema (System.getProperties()):

withSystemProperty("foo", "bar") {
System.getProperty("foo") shouldBe "bar"
}

Y con listeners equivalentes:

    class MyTest : FreeSpec() {

override fun listeners() = listOf(SystemPropertyListener("foo", "bar"))

init {
"MyTest" {
System.getProperty("foo") shouldBe "bar"
}
}

}

Gestor de seguridad del sistema

De forma análoga, con el gestor de seguridad puedes sobrescribir el Security Manager del sistema (System.getSecurityManager())


withSecurityManager(myManager) {
// Usage of security manager
}

Y sus listeners correspondientes:

    class MyTest : FreeSpec() {

override fun listeners() = listOf(SecurityManagerListener(myManager))

init {
// Use my security manager
}

}

Extensiones para System.exit

Si necesitas verificar que tu código llama a System.exit, usa los System Exit Listeners. Estos listeners lanzarán una excepción cuando se invoque System.exit, permitiéndote capturarla y validar:


class MyTest : FreeSpec() {

override fun listeners() = listOf(SpecSystemExitListener)

init {
"Catch exception" {
val thrown: SystemExitException = shouldThrow<SystemExitException> {
System.exit(22)
}

thrown.exitCode shouldBe 22
}
}
}

Listeners para bloquear stdout/stderr

Quizás quieras garantizar que no quedan mensajes de depuración residuales o asegurar que siempre usas un Logger para tus trazas.

Para ello, Kotest ofrece NoSystemOutListener y NoSystemErrListener. Estos listeners bloquean cualquier mensaje dirigido directamente a System.out o System.err, respectivamente:

    // In Project or in Spec
override fun listeners() = listOf(NoSystemOutListener, NoSystemErrListener)

Listeners para Locale/Zona horaria

Algunos códigos utilizan o son sensibles al Locale y zona horaria predeterminados. En lugar de manipular estos valores manualmente, ¡deja que Kotest lo gestione por ti!

withDefaultLocale(Locale.FRANCE) {
println("My locale is now France! Très bien!")
}

withDefaultTimeZone(TimeZone.getTimeZone(ZoneId.of("America/Sao_Paulo"))) {
println("My timezone is now America/Sao_Paulo! Muito bem!")
}

Y mediante los listeners correspondientes:

  // In Project or in Spec
override fun listeners() = listOf(
LocaleTestListener(Locale.FRANCE),
TimeZoneTestListener(TimeZone.getTimeZone(ZoneId.of("America/Sao_Paulo")))
)