Kotest, Spring, TestContainers i deserializacja immutable data class

0

Postanowiłem sprawdzić kotest w akcji i mam kilka pytań, zebrałem więc kilka niewiadomych do jednego testu:

class ProjectConfig : AbstractProjectConfig() {
    override fun extensions() = listOf(SpringAutowireConstructorExtension)
}

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AuthenticatorTest(@LocalServerPort val port: Int) : BehaviorSpec({

    val mongoContainer = GenericContainer<Nothing>("mongo:latest")
    listener(mongoContainer.perSpec())

    val restTemplate = RestTemplate()

    given("valid authenticate command") {
        val command = AuthenticationCommand("[email protected]", "qwe123")
        `when`("authenticate endpoint gets invoked") {
            val response = restTemplate.postForEntity(url(port, "/api/auth"), command, AuthenticationResult::class.java)
            then("http status is 200 ok") {
                response.statusCode shouldBe HttpStatus.OK
            }
        }
    }
})

fun url(port: Int, endpoint: String) = "http://localhost:$port$endpoint"
  1. (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT), restTemplate, sklejanie urla z portem w ten sposób jak wyżej - czy jest jakiś lepszy sposób do testowania http w Springu z kotest?

  2. listener(mongoContainer.perSpec()) o ile dobrze rozumiem, to tworzy to nowy kontener z mongo per każdy spec? Jak stworzyć jeden kontener i współdzielić go między wszystkie testy w aplikacji? Przed testami wolę zrobić dropa kolekcji niż podnosić od nowa kontener przy każdej nowej klasie testów

  3. val response = restTemplate.postForEntity(url(port, "/api/auth"), command, AuthenticationResult::class.java) nie działa.
    Implementacja tej klasy to data class AuthenticationResult(val userId: String, val token: String), niestety dostaję

(no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Ten test przechodzi gdy zwracany typ dam jako Any, dostaję wtedy odpowiedź w postaci mapy, obstawiam że jednak da się to skonfigurować tak by dostawać pełny obiekt?

1
  1. Moja rada to napisać sobie klienta do twojej aplikacji/serwisu. Zrób osobny moduł który ukrywa całą komunikacje. W teście robisz wtedy new MyClient(host, port) a potem result = myClient.someCall(someParam). To nie ma nic wspólnego z kotestem oczywiście, to jest po prostu podstawa dobrego designu.
  2. Brakuje ci pewnie takiego pana https://search.maven.org/search?q=a:jackson-module-kotlin%20AND%20g:com.fasterxml.jackson.module
1

Jeśli chcesz stawiać jeden kontener na wszystkie testy to możesz to zrobić w bloku statycznym:
https://www.testcontainers.org/test_framework_integration/manual_lifecycle_control/

1 użytkowników online, w tym zalogowanych: 0, gości: 1