반응형
앞서 Java로 작성했던 Testcontainers로 테스트 코드 만들기를
Kotlin으로도 작성해봅시다.
이번에는 Mysql이 아닌 Redis를 사용한다고 가정합니다.
또한 Webflux 기반 테스트 환경 구축방법에 대해 포스팅합니다.
로컬환경은 아래와 같습니다.
- Windows 10
- JDK 17
- Kotlin 1.8
- Springboot 3.1.4
- Testcontainers 1.17.7
1. 의존성 추가
아래와 같이 build.gradle.kts에 의존성을 추가해줍니다.
/* build.gradle.kts */
dependencies {
...(중략)
testImplementation("io.mockk:mockk:1.10.4")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.testcontainers:testcontainers:1.17.6")
testImplementation("org.testcontainers:junit-jupiter:1.17.6")
}
2. 코드 추가
Springboot에서 Redis 사용을 위한 아래 컴포넌트를 추가해줍니다.
@Configuration
class RedisConfig {
@Bean
fun reactiveRedisTemplate(reactiveRedisConnectionFactory: ReactiveRedisConnectionFactory): ReactiveRedisTemplate<String, Any> {
val serializer = Jackson2JsonRedisSerializer(Any::class.java)
val builder = RedisSerializationContext.newSerializationContext<String, Any>(StringRedisSerializer())
val context = builder.value(serializer).build()
return ReactiveRedisTemplate(reactiveRedisConnectionFactory, context)
}
}
다음에는 실제 테스트 코드를 작성해봅시다.
3. 추상클래스 추가
아래와 src/test 내에 추상 클래스를 작성해봅니다.
@SpringBootTest
@ActiveProfiles("test")
abstract class IntegrationTest {
companion object {
private var redis: GenericContainer<*>
private val REDIS_IMAGE_NAME = "redis:6.2.7-alpine"
private val PORT = 6379
init {
redis = GenericContainer(REDIS_IMAGE_NAME)
.withExposedPorts(PORT)
.withReuse(true)
}
@JvmStatic
fun get(): GenericContainer<*> {
return redis;
}
@JvmStatic
@BeforeAll
fun beforeAll() {
if (!redis.isRunning()) {
redis.start()
}
}
@JvmStatic
@AfterAll
fun afterAll() {
redis.close()
}
@JvmStatic
@DynamicPropertySource
fun properties(registry: DynamicPropertyRegistry) {
registry.add("spring.data.redis.host", redis::getHost)
registry.add("spring.data.redis.port", redis::getFirstMappedPort)
}
}
}
- 추상클래스내에 static 멤버를 추가합니다.
- 클래스 초기화 시 static 멤버가 생성되고 이 때 RedisContainer를 띄우게 됩니다.
- @JvmStatic 어노테이션으로 static 멤버로 만들어 줄 수 있습니다.
- @DynamicPropertySource 어노테이션으로 Springboot가 연동할 Redis의 host/port를 동적으로 변환해줍니다.
이제 이 추상클래스를 상속 받아 API 테스트 코드를 작성해봅시다.
4. API 테스트 코드 추가
@ExtendWith(MockitoExtension::class)
@ExtendWith(SpringExtension::class)
@AutoConfigureWebTestClient
class HelloControllerTest @Autowired constructor(
val webTestClient: WebTestClient
) : IntegrationTest() {
@Test
fun `redis 입력 테스트`() {
val data = """
{
"key": "test",
"field":"2",
"value":"abc"
}
""".trimIndent()
webTestClient.post()
.uri("/api/hello/redis")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(JsonUtil.convertToMap(data)))
.exchange()
.expectStatus().isOk
}
}
- IntegrationTest 클래스를 상속받습니다.
- 여기서는 Webflux를 사용하기 때문에 API 테스트 도구로 MockMvc가 아닌 WebTestClient를 사용합니다.
반응형
'개발 이야기 > Springboot' 카테고리의 다른 글
Springboot에서 ArchUnit 사용해서 아키텍처 테스트 (0) | 2024.01.27 |
---|---|
Springboot에서 AWS SQS 사용 (with Kotlin) (0) | 2024.01.18 |
Testcontainers로 테스트 코드 만들기 (0) | 2024.01.07 |
Springboot Application 로드 시 외부 파일 읽기 & 환경 설정 (0) | 2024.01.07 |
Springboot에서 ResourceTransformer 적용하여 뷰 페이지 렌더링 (0) | 2024.01.07 |