Kotestシステム拡張(System Extensions)
システム拡張
java.lang.Systemを使用するコードをテストする必要がある場合、Kotestはシステムを変更し、各テスト後に復元できる拡張機能を提供する。この拡張はJVMでのみ使用できる。
この拡張を使用するには、プロジェクトに依存関係を追加する。
io.kotest:kotest-extensions-jvm:${version}
システム環境
システム環境拡張を使用すると、システム環境がどのように動作するかをシミュレートできる。つまり、System.getenv()から得られるものをシミュレートできる。
Kotestは、特定スコープのシステム環境を提供するいくつかの拡張関数を提供している。
withEnvironment("FooKey", "BarValue") {
System.getenv("FooKey") shouldBe "BarValue" // System environment overridden!
}
この拡張機能では、MapやPairのリストを通じて複数の値を使用することもできる。
withEnvironment(mapOf("FooKey" to "BarValue", "BarKey" to "FooValue")) {
// Use FooKey and BarKey
}
この関数は、キーと値が現在の環境にない場合は追加し、ある場合は上書きする。関数によって触れられていないキーは環境にそのまま残り、変更されない。
拡張関数の代わりに、提供されているリスナーを使用して、より広いスコープにこの機能を適用することもできる。Spec/テスト単位レベル向けの代替手段と、プロジェクトレベル向けの代替手段がある。
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.system.SystemEnvironmentTestListener
import io.kotest.matchers.shouldBe
class MyTest : FreeSpec() {
override fun listeners() = listOf(SystemEnvironmentTestListener("foo", "bar"))
init {
"MyTest" {
System.getenv("foo") shouldBe "bar"
}
}
}
import io.kotest.core.config.AbstractProjectConfig
import io.kotest.extensions.system.SystemEnvironmentProjectListener
class ProjectConfig : AbstractProjectConfig() {
override fun listeners() = listOf(SystemEnvironmentProjectListener("foo", "bar"))
}
システムプロパティ拡張
環境拡張と同じ方法で、システムプロパティ(System.getProperties())を上書きできる。
withSystemProperty("foo", "bar") {
System.getProperty("foo") shouldBe "bar"
}
そして、リスナーとしても提供される。
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.system.SystemPropertyTestListener
import io.kotest.matchers.shouldBe
class MyTest : FreeSpec() {
override fun listeners() = listOf(SystemPropertyTestListener("foo", "bar"))
init {
"MyTest" {
System.getProperty("foo") shouldBe "bar"
}
}
}
システムセキュリティマネージャ
同様に、システムセキュリティマネージャを使用すると、システムセキュリティマネージャ(System.getSecurityManager())を上書きできる。
withSecurityManager(myManager) {
// Usage of security manager
}
そして、リスナーとしても提供される。
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.system.SecurityManagerListener
class MyTest : FreeSpec() {
override fun listeners() = listOf(SecurityManagerListener(myManager))
init {
// Use my security manager
}
}
システム終了拡張
コードがSystem.exitを呼び出すかテストしたい場合がある。そのためにシステム終了リスナーを使用できる。リスナーはSystem.exitが呼び出されると例外を投げるため、それを捕捉して確認できる。
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.system.SpecSystemExitListener
import io.kotest.extensions.system.SystemExitException
import io.kotest.matchers.shouldBe
class MyTest : FreeSpec() {
override fun listeners() = listOf(SpecSystemExitListener)
init {
"Catch exception" {
val thrown: SystemExitException = shouldThrow<SystemExitException> {
System.exit(22)
}
thrown.exitCode shouldBe 22
}
}
}
no-stdout/no-stderrリスナー
デバッグメッセージを残していないか、またはロギングに常にロガーを使用しているかを確認したい場合がある。
このために、KotestはNoSystemOutListenerとNoSystemErrListenerを提供する。これらのリスナーは、それぞれSystem.outまたはSystem.errへ直接メッセージを出力することを許可しない。
// In Project or in Spec
override fun listeners() = listOf(NoSystemOutListener, NoSystemErrListener)
Locale/Timezoneリスナー
一部のコードはデフォルトのLocaleおよびTimezoneを使用したり、それに影響を受けたりする。システムデフォルトを直接操作する代わりに、Kotestに処理させることができる。
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!")
}
そして、リスナーとしても提供される。
// In Project or in Spec
override fun listeners() = listOf(
LocaleTestListener(Locale.FRANCE),
TimeZoneTestListener(TimeZone.getTimeZone(ZoneId.of("America/Sao_Paulo")))
)