upgrade to Spring Boot 4.2.1
This commit is contained in:
@@ -48,7 +48,7 @@ All production code lives under `de.hoennig.gittally`. Commands are in the `comm
|
|||||||
|
|
||||||
## Testing Conventions
|
## Testing Conventions
|
||||||
|
|
||||||
Tests use **Kotest `FunSpec`** style. `SpringExtension` is registered globally in `KotestProjectConfig` — do not add it per-spec.
|
Tests use **Kotest `FunSpec`** style. `SpringExtension` is registered globally in `io.kotest.provided.ProjectConfig` — do not add it per-spec.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
class MyTest : FunSpec() {
|
class MyTest : FunSpec() {
|
||||||
@@ -63,7 +63,21 @@ Use `shouldBe`, `shouldNotBe`, `shouldThrow` etc. from `io.kotest.matchers`.
|
|||||||
|
|
||||||
### Mocking in Spring Slice Tests
|
### Mocking in Spring Slice Tests
|
||||||
|
|
||||||
`springmockk` is not compatible with the target Spring Boot version (4.0). The `@MockkBean` annotation is unavailable. Use `@TestConfiguration` to register MockK mocks as Spring beans:
|
Use `@MockkBean` from `springmockk` to inject MockK mocks into the Spring context:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
@WebMvcTest(SomeController::class)
|
||||||
|
class SomeControllerTest : FunSpec() {
|
||||||
|
@MockkBean
|
||||||
|
lateinit var someService: SomeService
|
||||||
|
init {
|
||||||
|
beforeEach { clearMocks(someService) }
|
||||||
|
// full MockK syntax: every { } / verify { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, register mocks via `@TestConfiguration` without the springmockk dependency:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@WebMvcTest(SomeController::class)
|
@WebMvcTest(SomeController::class)
|
||||||
@@ -87,7 +101,5 @@ Pure unit tests (no Spring context) use MockK directly without any Spring wiring
|
|||||||
All major decisions are in `docs/adrs/`. Run `adr-status` (after `source .envrc`) for a one-line summary of each. Decisions in force:
|
All major decisions are in `docs/adrs/`. Run `adr-status` (after `source .envrc`) for a one-line summary of each. Decisions in force:
|
||||||
|
|
||||||
- **Test framework**: Kotest + MockK + WireMock + Testcontainers (ADR 0001)
|
- **Test framework**: Kotest + MockK + WireMock + Testcontainers (ADR 0001)
|
||||||
- **Gradle**: 8.14 target (currently 8.8; upgrade pending Spring Boot 4.0 migration) (ADR 0002)
|
- **Gradle**: 8.14.5 (ADR 0002)
|
||||||
- **Spring Boot**: 4.0 target (currently 3.3.4 — pending upgrade; 3.3.x is EOL) (ADR 0003)
|
- **Spring Boot**: 4.0.6 (ADR 0003)
|
||||||
|
|
||||||
The Spring Boot and Gradle upgrades are open work items documented in the ADRs. When upgrading, verify `ApplicationContextTest` passes as the primary smoke test.
|
|
||||||
|
|||||||
+15
-15
@@ -1,11 +1,11 @@
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.springframework.boot") version "3.3.4"
|
id("org.springframework.boot") version "4.0.6"
|
||||||
id("io.spring.dependency-management") version "1.1.6"
|
id("io.spring.dependency-management") version "1.1.7"
|
||||||
id("org.jlleitschuh.gradle.ktlint") version "12.1.1"
|
id("org.jlleitschuh.gradle.ktlint") version "14.2.0"
|
||||||
kotlin("jvm") version "1.9.25"
|
kotlin("jvm") version "2.2.0"
|
||||||
kotlin("plugin.spring") version "1.9.25"
|
kotlin("plugin.spring") version "2.2.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "de.hoennig"
|
group = "de.hoennig"
|
||||||
@@ -29,26 +29,26 @@ dependencies {
|
|||||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
|
||||||
// Kotest
|
// Kotest
|
||||||
testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
|
testImplementation("io.kotest:kotest-runner-junit5:6.1.5")
|
||||||
testImplementation("io.kotest:kotest-assertions-core:5.9.1")
|
testImplementation("io.kotest:kotest-assertions-core:6.1.5")
|
||||||
testImplementation("io.kotest.extensions:kotest-extensions-spring:1.3.0")
|
testImplementation("io.kotest:kotest-extensions-spring:6.1.5")
|
||||||
|
|
||||||
// MockK
|
// MockK
|
||||||
testImplementation("io.mockk:mockk:1.13.11")
|
testImplementation("io.mockk:mockk:1.13.11")
|
||||||
testImplementation("com.ninja-squad:springmockk:4.0.2")
|
testImplementation("com.ninja-squad:springmockk:5.0.1")
|
||||||
|
|
||||||
// WireMock
|
// WireMock
|
||||||
testImplementation("org.wiremock.integrations:wiremock-spring-boot:3.1.0")
|
testImplementation("org.wiremock.integrations:wiremock-spring-boot:4.2.1")
|
||||||
|
|
||||||
// Testcontainers (versions managed by Spring Boot BOM)
|
// Testcontainers (versions managed by Spring Boot BOM)
|
||||||
testImplementation("org.springframework.boot:spring-boot-testcontainers")
|
testImplementation("org.springframework.boot:spring-boot-testcontainers")
|
||||||
testImplementation("org.testcontainers:testcontainers")
|
testImplementation("org.testcontainers:testcontainers")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
kotlin {
|
||||||
kotlinOptions {
|
compilerOptions {
|
||||||
freeCompilerArgs += "-Xjsr305=strict"
|
freeCompilerArgs.addAll("-Xjsr305=strict")
|
||||||
jvmTarget = "21"
|
jvmTarget = JvmTarget.JVM_21
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
**Status:**
|
**Status:**
|
||||||
- proposed: 2026-06-09
|
- proposed: 2026-06-09
|
||||||
- accepted: -
|
- accepted: 2026-06-09
|
||||||
- rejected: -
|
- rejected: -
|
||||||
- superseded: -
|
- superseded: -
|
||||||
|
|
||||||
**Decision [proposed]:** Gradle 8.14 — minimum required by Spring Boot 4.0; Gradle 9 deferred until openapi-generator and ktlint-gradle confirm compatibility.
|
**Decision [accepted]:** Gradle 8.14.5 — minimum required by Spring Boot 4.0; Gradle 9 deferred until openapi-generator and ktlint-gradle confirm compatibility.
|
||||||
|
|
||||||
## Context and Problem Statement
|
## Context and Problem Statement
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ It has a direct dependency chain:
|
|||||||
- Plugin ecosystem readiness varies: the
|
- Plugin ecosystem readiness varies: the
|
||||||
[openapi-generator Gradle plugin](https://github.com/OpenAPITools/openapi-generator/issues/22084)
|
[openapi-generator Gradle plugin](https://github.com/OpenAPITools/openapi-generator/issues/22084)
|
||||||
has a known Gradle 9 issue in its generated build files, and
|
has a known Gradle 9 issue in its generated build files, and
|
||||||
[ktlint-gradle 12.1.1](https://github.com/JLLeitschuh/ktlint-gradle) Gradle 9 support
|
[ktlint-gradle 14.2.0](https://github.com/JLLeitschuh/ktlint-gradle) Gradle 9 support
|
||||||
needs verification.
|
needs verification.
|
||||||
- The [`io.spring.dependency-management` plugin](https://github.com/spring-gradle-plugins/dependency-management-plugin)
|
- The [`io.spring.dependency-management` plugin](https://github.com/spring-gradle-plugins/dependency-management-plugin)
|
||||||
used to resolve the Spring BOM has known friction with Gradle 9
|
used to resolve the Spring BOM has known friction with Gradle 9
|
||||||
@@ -56,9 +56,9 @@ current 8.8 is necessary regardless of whether Gradle 9 is chosen.
|
|||||||
* Gradle 8.14 (minimum for Spring Boot 4.0)
|
* Gradle 8.14 (minimum for Spring Boot 4.0)
|
||||||
* Gradle 9.x
|
* Gradle 9.x
|
||||||
|
|
||||||
### [Gradle 8.x](https://docs.gradle.org/8.8/release-notes.html)
|
### [Gradle 8.x](https://docs.gradle.org/8.14.5/release-notes.html)
|
||||||
|
|
||||||
The currently configured series (wrapper at 8.8, to be bumped to 8.14+ for Spring Boot 4.0).
|
The currently configured series (wrapper at 8.14.5, upgraded from 8.8 as part of the Spring Boot 4.0 migration).
|
||||||
|
|
||||||
#### Advantages
|
#### Advantages
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ The current major release (9.5.1 as of May 2026), officially supported alongside
|
|||||||
- [openapi-generator-gradle-plugin](https://github.com/OpenAPITools/openapi-generator/issues/22084)
|
- [openapi-generator-gradle-plugin](https://github.com/OpenAPITools/openapi-generator/issues/22084)
|
||||||
has a known Gradle 9 issue in generated `build.gradle` files; impact on the spec-first
|
has a known Gradle 9 issue in generated `build.gradle` files; impact on the spec-first
|
||||||
code generation task specifically needs verification.
|
code generation task specifically needs verification.
|
||||||
- [ktlint-gradle 12.1.1](https://github.com/JLLeitschuh/ktlint-gradle) Gradle 9 support
|
- [ktlint-gradle 14.2.0](https://github.com/JLLeitschuh/ktlint-gradle) Gradle 9 support
|
||||||
needs verification.
|
needs verification.
|
||||||
- Configuration Cache mandatory means any currently uncached plugin will break the build
|
- Configuration Cache mandatory means any currently uncached plugin will break the build
|
||||||
until updated, complicating initial setup.
|
until updated, complicating initial setup.
|
||||||
@@ -106,7 +106,7 @@ The main reasons:
|
|||||||
- Gradle 9 is technically compatible with Spring Boot 4.0, but the mandatory Configuration Cache
|
- Gradle 9 is technically compatible with Spring Boot 4.0, but the mandatory Configuration Cache
|
||||||
creates unacceptable risk until the openapi-generator-gradle-plugin Gradle 9 compatibility
|
creates unacceptable risk until the openapi-generator-gradle-plugin Gradle 9 compatibility
|
||||||
is confirmed (see [issue #22084](https://github.com/OpenAPITools/openapi-generator/issues/22084)).
|
is confirmed (see [issue #22084](https://github.com/OpenAPITools/openapi-generator/issues/22084)).
|
||||||
- ktlint-gradle 12.1.1 Gradle 9 support is unverified; a formatter breaking the build on day
|
- ktlint-gradle 14.2.0 Gradle 9 support is unverified; a formatter breaking the build on day
|
||||||
one is a poor start.
|
one is a poor start.
|
||||||
|
|
||||||
Upgrade trigger: revisit Gradle 9 once openapi-generator and ktlint-gradle confirm support.
|
Upgrade trigger: revisit Gradle 9 once openapi-generator and ktlint-gradle confirm support.
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
**Status:**
|
**Status:**
|
||||||
- proposed: 2026-06-09
|
- proposed: 2026-06-09
|
||||||
- accepted: -
|
- accepted: 2026-06-09
|
||||||
- rejected: -
|
- rejected: -
|
||||||
- superseded: -
|
- superseded: -
|
||||||
|
|
||||||
**Decision [proposed]:** Spring Boot 4.0 — only actively-supported version; springmockk workaround via @TestConfiguration until a compatible release is published.
|
**Decision [accepted]:** Spring Boot 4.0.6 — only actively-supported version; springmockk 5.0.1 provides @MockkBean for Spring Boot 4.0.
|
||||||
|
|
||||||
## Context and Problem Statement
|
## Context and Problem Statement
|
||||||
|
|
||||||
@@ -34,12 +34,12 @@ Spring Boot 4.0 moves to Spring Framework 7 and Jakarta EE 11.
|
|||||||
|
|
||||||
The key ecosystem dependencies and their Spring Boot 4.0 compatibility status:
|
The key ecosystem dependencies and their Spring Boot 4.0 compatibility status:
|
||||||
|
|
||||||
| Dependency | Role | Spring Boot 4.0 status |
|
| Dependency | Version | Role | Spring Boot 4.0 status |
|
||||||
|---|---|---|
|
|---|---|---|---|
|
||||||
| [picocli-spring-boot-starter](https://picocli.info/) | CLI wiring | Untested; last documented target is Spring Boot 3.1. The integration is minimal (one `IFactory` bean), so it likely works in practice. |
|
| [picocli-spring-boot-starter](https://picocli.info/) | 4.7.6 | CLI wiring | **Compatible** — `ApplicationContextTest` confirms context wiring works. |
|
||||||
| [springmockk](https://github.com/Ninja-Squad/springmockk) | `@MockkBean` in tests | **Incompatible** — confirmed Spring Boot 3.x only. |
|
| [springmockk](https://github.com/Ninja-Squad/springmockk) | 5.0.1 | `@MockkBean` in tests | **Compatible** — 5.x released specifically for Spring Boot 4.0; `@MockkBean` verified. |
|
||||||
| [kotest-extensions-spring](https://github.com/kotest/kotest-extensions-spring) | Kotest + `@SpringBootTest` | Compatibility unconfirmed. |
|
| [kotest-extensions-spring](https://github.com/kotest/kotest-extensions-spring) | 6.1.5 | Kotest + `@SpringBootTest` | **Compatible** — 6.x (new groupId `io.kotest`) required; config moved to `io.kotest.provided.ProjectConfig`. |
|
||||||
| [wiremock-spring-boot](https://wiremock.org/docs/spring-boot/) | HTTP stubbing in tests | **Compatible** — Spring Boot 4.0 explicitly supported since January 2026. |
|
| [wiremock-spring-boot](https://wiremock.org/docs/spring-boot/) | 4.2.1 | HTTP stubbing in tests | **Compatible** — Spring Boot 4.0 explicitly supported since January 2026. |
|
||||||
|
|
||||||
## Considered Options
|
## Considered Options
|
||||||
|
|
||||||
@@ -76,12 +76,9 @@ The current and only actively-supported major release.
|
|||||||
|
|
||||||
#### Disadvantages
|
#### Disadvantages
|
||||||
|
|
||||||
- **springmockk is incompatible.** The `@MockkBean` / `@SpykBean` annotations are not available.
|
- **springmockk 5.x is required.** Version 4.x is Spring Boot 3.x only. Version 5.0.1 adds
|
||||||
This matters in particular for `@WebMvcTest` (controller error-behaviour) and
|
Spring Boot 4.0 support; `@MockkBean` / `@SpykBean` work as expected.
|
||||||
`@DataJpaTest`-adjacent tests where collaborators need to be mocked in the Spring context.
|
As an alternative, register MockK mocks via `@TestConfiguration` without the springmockk dependency:
|
||||||
The workaround is to register MockK mocks as Spring beans via `@TestConfiguration`,
|
|
||||||
which preserves full MockK syntax (`every { }`, `verify { }`) at the cost of one
|
|
||||||
inner configuration class per test file and an explicit `clearMocks()` call in `beforeEach`:
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@WebMvcTest(SomeController::class)
|
@WebMvcTest(SomeController::class)
|
||||||
@Import(SomeControllerTest.Mocks::class)
|
@Import(SomeControllerTest.Mocks::class)
|
||||||
@@ -93,17 +90,12 @@ The current and only actively-supported major release.
|
|||||||
@Autowired lateinit var someService: SomeService
|
@Autowired lateinit var someService: SomeService
|
||||||
init {
|
init {
|
||||||
beforeEach { clearMocks(someService) }
|
beforeEach { clearMocks(someService) }
|
||||||
// full MockK syntax available
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
This is more verbose than `@MockkBean` but avoids mixing Mockito and MockK.
|
- **picocli-spring-boot-starter** context wiring confirmed via `ApplicationContextTest`.
|
||||||
Revisit once springmockk publishes a Spring Boot 4.0-compatible release.
|
- **kotest-extensions-spring 6.x** (groupId `io.kotest`) is required for Spring Boot 4.0.
|
||||||
- **picocli-spring-boot-starter is untested against Spring Boot 4.0.**
|
The project config must be placed at `io.kotest.provided.ProjectConfig` (Kotest 6 discovery requirement).
|
||||||
The risk is low (the auto-configuration is a single `IFactory` bean with no framework-version-specific API),
|
|
||||||
but it cannot be assumed safe until verified by a running context test.
|
|
||||||
- **kotest-extensions-spring** compatibility needs verification before the first
|
|
||||||
`@SpringBootTest` test is written.
|
|
||||||
- Relatively new GA; fewer community examples for the 4.0 generation.
|
- Relatively new GA; fewer community examples for the 4.0 generation.
|
||||||
|
|
||||||
## Decision Outcome
|
## Decision Outcome
|
||||||
@@ -124,9 +116,4 @@ The main reasons:
|
|||||||
- kotest-extensions-spring compatibility must be verified before the
|
- kotest-extensions-spring compatibility must be verified before the
|
||||||
first `@SpringBootTest` test is written.
|
first `@SpringBootTest` test is written.
|
||||||
|
|
||||||
Open items before the code is upgraded:
|
All ecosystem blockers are resolved. The codebase runs Spring Boot 4.0.6.
|
||||||
1. Bump Spring Boot to 4.0.6 and verify `ApplicationContextTest` still passes.
|
|
||||||
2. Confirm picocli-spring-boot-starter works under the new context.
|
|
||||||
3. Confirm kotest-extensions-spring works with Spring Boot 4.0.
|
|
||||||
4. Replace `@MockkBean` usages with the `@TestConfiguration` + `mockk()` pattern
|
|
||||||
until springmockk publishes a compatible release.
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ class GitTallyApplication
|
|||||||
class CliRunner(
|
class CliRunner(
|
||||||
private val factory: IFactory,
|
private val factory: IFactory,
|
||||||
private val rootCommand: GitTallyCommand,
|
private val rootCommand: GitTallyCommand,
|
||||||
) : CommandLineRunner, ExitCodeGenerator {
|
) : CommandLineRunner,
|
||||||
|
ExitCodeGenerator {
|
||||||
private var exitCode = 0
|
private var exitCode = 0
|
||||||
|
|
||||||
override fun run(vararg args: String) {
|
override fun run(vararg args: String) {
|
||||||
|
|||||||
@@ -15,7 +15,5 @@ import picocli.CommandLine.Command
|
|||||||
description = ["Lightweight, declarative CI/CD system"],
|
description = ["Lightweight, declarative CI/CD system"],
|
||||||
)
|
)
|
||||||
class GitTallyCommand : Runnable {
|
class GitTallyCommand : Runnable {
|
||||||
override fun run() {
|
override fun run(): Unit = throw CommandLine.ParameterException(CommandLine(this), "Specify a subcommand")
|
||||||
throw CommandLine.ParameterException(CommandLine(this), "Specify a subcommand")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package de.hoennig.gittally
|
|
||||||
|
|
||||||
import io.kotest.core.config.AbstractProjectConfig
|
|
||||||
import io.kotest.extensions.spring.SpringExtension
|
|
||||||
|
|
||||||
object KotestProjectConfig : AbstractProjectConfig() {
|
|
||||||
override fun extensions() = listOf(SpringExtension)
|
|
||||||
}
|
|
||||||
@@ -10,14 +10,15 @@ interface Greeter {
|
|||||||
fun greet(name: String): String
|
fun greet(name: String): String
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockKSmokeTest : FunSpec({
|
class MockKSmokeTest :
|
||||||
|
FunSpec({
|
||||||
|
|
||||||
test("mockk stubs and verifies") {
|
test("mockk stubs and verifies") {
|
||||||
val greeter = mockk<Greeter>()
|
val greeter = mockk<Greeter>()
|
||||||
every { greeter.greet("world") } returns "hello, world"
|
every { greeter.greet("world") } returns "hello, world"
|
||||||
|
|
||||||
greeter.greet("world") shouldBe "hello, world"
|
greeter.greet("world") shouldBe "hello, world"
|
||||||
|
|
||||||
verify(exactly = 1) { greeter.greet("world") }
|
verify(exactly = 1) { greeter.greet("world") }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ interface MessageService {
|
|||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Import(SpringMockKSmokeTest.Mocks::class)
|
@Import(SpringMockKSmokeTest.Mocks::class)
|
||||||
class SpringMockKSmokeTest : FunSpec() {
|
class SpringMockKSmokeTest : FunSpec() {
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
class Mocks {
|
class Mocks {
|
||||||
@Bean
|
@Bean
|
||||||
@@ -47,7 +46,6 @@ class SpringMockKSmokeTest : FunSpec() {
|
|||||||
/** Verifies whether @MockkBean works with the current Spring Boot version (springmockk 4.0.2). */
|
/** Verifies whether @MockkBean works with the current Spring Boot version (springmockk 4.0.2). */
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class MockkBeanSmokeTest : FunSpec() {
|
class MockkBeanSmokeTest : FunSpec() {
|
||||||
|
|
||||||
@MockkBean
|
@MockkBean
|
||||||
lateinit var messageService: MessageService
|
lateinit var messageService: MessageService
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ import io.kotest.matchers.shouldBe
|
|||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.utility.DockerImageName
|
import org.testcontainers.utility.DockerImageName
|
||||||
|
|
||||||
class TestcontainersSmokeTest : FunSpec({
|
class TestcontainersSmokeTest :
|
||||||
|
FunSpec({
|
||||||
|
|
||||||
test("Testcontainers starts a container") {
|
test("Testcontainers starts a container") {
|
||||||
val container = GenericContainer(DockerImageName.parse("alpine:3"))
|
val container =
|
||||||
.withCommand("sh", "-c", "sleep 30")
|
GenericContainer(DockerImageName.parse("alpine:3"))
|
||||||
container.start()
|
.withCommand("sh", "-c", "sleep 30")
|
||||||
container.isRunning shouldBe true
|
container.start()
|
||||||
container.stop()
|
container.isRunning shouldBe true
|
||||||
}
|
container.stop()
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -11,22 +11,24 @@ import java.net.http.HttpClient
|
|||||||
import java.net.http.HttpRequest
|
import java.net.http.HttpRequest
|
||||||
import java.net.http.HttpResponse
|
import java.net.http.HttpResponse
|
||||||
|
|
||||||
class WireMockSmokeTest : FunSpec({
|
class WireMockSmokeTest :
|
||||||
|
FunSpec({
|
||||||
|
|
||||||
val server = WireMockServer(options().dynamicPort())
|
val server = WireMockServer(options().dynamicPort())
|
||||||
|
|
||||||
beforeSpec { server.start() }
|
beforeSpec { server.start() }
|
||||||
afterSpec { server.stop() }
|
afterSpec { server.stop() }
|
||||||
|
|
||||||
test("WireMock stubs an HTTP endpoint") {
|
test("WireMock stubs an HTTP endpoint") {
|
||||||
server.stubFor(get("/ping").willReturn(aResponse().withStatus(200).withBody("pong")))
|
server.stubFor(get("/ping").willReturn(aResponse().withStatus(200).withBody("pong")))
|
||||||
|
|
||||||
val response = HttpClient.newHttpClient().send(
|
val response =
|
||||||
HttpRequest.newBuilder().uri(URI.create("http://localhost:${server.port()}/ping")).build(),
|
HttpClient.newHttpClient().send(
|
||||||
HttpResponse.BodyHandlers.ofString(),
|
HttpRequest.newBuilder().uri(URI.create("http://localhost:${server.port()}/ping")).build(),
|
||||||
)
|
HttpResponse.BodyHandlers.ofString(),
|
||||||
|
)
|
||||||
|
|
||||||
response.statusCode() shouldBe 200
|
response.statusCode() shouldBe 200
|
||||||
response.body() shouldBe "pong"
|
response.body() shouldBe "pong"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package io.kotest.provided
|
||||||
|
|
||||||
|
import io.kotest.core.config.AbstractProjectConfig
|
||||||
|
import io.kotest.extensions.spring.SpringExtension
|
||||||
|
|
||||||
|
object ProjectConfig : AbstractProjectConfig() {
|
||||||
|
override val extensions = listOf(SpringExtension())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user