chore(backend): add integration test for PingRepository with Testcontainers setup

- Implemented a minimal integration test to validate persistence layer functionality.
- Configured PostgreSQL Testcontainer and Flyway migrations for testing.
- Added `TestPersistenceConfig` to isolate testing setup and avoid loading unnecessary components.
- Updated build script to include Testcontainers dependencies.
This commit is contained in:
2026-02-01 17:55:41 +01:00
parent 82139e0c2f
commit 6c8accb9b6
3 changed files with 105 additions and 0 deletions
@@ -42,6 +42,7 @@ dependencies {
// === Testing ===
testImplementation(libs.bundles.testing.jvm)
testImplementation(libs.bundles.testcontainers) // WICHTIG: Testcontainer Bundle hinzugefügt
testImplementation(libs.spring.boot.starter.test)
testImplementation(libs.spring.security.test)
}
@@ -0,0 +1,88 @@
package at.mocode.ping.infrastructure.persistence
import at.mocode.ping.domain.Ping
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.context.annotation.Import
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.DynamicPropertyRegistry
import org.springframework.test.context.DynamicPropertySource
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers
import java.time.Instant
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toJavaUuid
/**
* Minimaler Integrationstest für die Persistenz-Schicht.
* Prüft:
* 1. Startet echte Postgres DB (via Testcontainers).
* 2. Führt Flyway-Migrationen aus (Schema-Erstellung).
* 3. Speichert und lädt eine Entity (Mapping-Check).
*/
@DataJpaTest
@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(classes = [TestPersistenceConfig::class]) // Nutzt isolierte Config statt Main-App
@Import(PingRepositoryAdapter::class) // Importiert den Adapter, den wir testen wollen
@ActiveProfiles("test") // WICHTIG: Lädt application-test.yaml
@OptIn(ExperimentalUuidApi::class)
class PingRepositoryTest {
@Autowired
private lateinit var repositoryAdapter: PingRepositoryAdapter
// Wir nutzen das Repository direkt, um zu prüfen, ob JPA funktioniert
@Autowired
private lateinit var springDataRepository: SpringDataPingRepository
companion object {
@Container
val postgres = PostgreSQLContainer("postgres:16-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test")
@JvmStatic
@DynamicPropertySource
fun registerPgProperties(registry: DynamicPropertyRegistry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl)
registry.add("spring.datasource.username", postgres::getUsername)
registry.add("spring.datasource.password", postgres::getPassword)
// Wichtig: Flyway muss laufen, um Tabellen zu erstellen
registry.add("spring.flyway.enabled") { "true" }
}
}
@Test
fun `should save and load ping entity`() {
// Given
val pingId = Uuid.generateV7()
val ping = Ping(
id = pingId,
message = "Integration Test Ping",
timestamp = Instant.now()
)
// When
repositoryAdapter.save(ping)
// Then (via Adapter)
val loadedPing = repositoryAdapter.findById(pingId)
assertThat(loadedPing).isNotNull
assertThat(loadedPing?.message).isEqualTo("Integration Test Ping")
assertThat(loadedPing?.id).isEqualTo(pingId)
// Then (Direct DB Check via Spring Data)
// Fix: Use toJavaUuid() instead of UUID.fromString(pingId.toString())
val entity = springDataRepository.findById(pingId.toJavaUuid())
assertThat(entity).isPresent
assertThat(entity.get().message).isEqualTo("Integration Test Ping")
}
}
@@ -0,0 +1,16 @@
package at.mocode.ping.infrastructure.persistence
import org.springframework.boot.SpringBootConfiguration
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.ComponentScan
/**
* Minimale Konfiguration für DataJpaTests.
* Verhindert, dass die echte PingServiceApplication geladen wird,
* welche einen weiten ComponentScan auslöst und damit Controller/Services lädt,
* die wir im Repository-Test nicht brauchen (und die Fehler verursachen).
*/
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages = ["at.mocode.ping.infrastructure.persistence"])
class TestPersistenceConfig