환경
IDE: intellij
SpringBootVersion: 2.7.18
Gradle: 8.5
Java: 17
해당 포스팅은
인프런 "코틀린 문법부터 실무까지 (자바 to 코틀린 실무)" 을 따라하면서 Java/Spring 프로젝트를 Kotlin/Spring 프로젝트로
점진적인으로 변환하는 내용을 담고 있습니다
다루는 내용
- JUnit5 -> Kotest
Kotest에서는 10가지의 다양한 스타일의 테스트 레이아웃을 제공합니다
테스트 레이아웃도 테스트 작성시 고민하는 요소인데 그런것도 레이아웃으로 제공해줍니다
참고: https://kotest.io/docs/framework/testing-styles.html
enum-when처럼 테스트 레이아웃도 짜잘하지만 개발자들 입장에서는 쓸데없는 고민하지 않게되는 행복코딩으로 거듭날 수 있는 이유들때문에 Kotlin은 상당히 매력적입니다
라이브러리 추가 방법
var kotestVersion = "5.8.0"
testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion")
util class Junit5 -> Kotest 변환
기존 JUnit 테스트 코드
class DateTimeUtilsTest {
@Test
void getLocalDateTimeStringTest() {
String result = DateTimeUtils.getLocalDateTimeString(
LocalDateTime.of(2023, 12, 21, 10, 10)
);
assertEquals("2023-12-21 탄생", result);
}
}
Convert to Java file to kotlin file 실행해줍니다
JUnit기반 테스트가 동작하도록 코드를 수정해줍니다
internal class DateTimeUtilsTest {
@Test
fun localDateTimeStringTest() {
val result = getLocalDateTimeString(
LocalDateTime.of(2023, 12, 21, 10, 10)
)
Assertions.assertEquals("2023-12-21 탄생", result)
}
}
kotest StringSpec으로 변환합니다
internal class DateTimeUtilsTest : StringSpec ({
"DateTimeUtil 출력 검증" {
val result = getLocalDateTimeString(
LocalDateTime.of(2023, 12, 21, 10, 10)
)
Assertions.assertEquals("2023-12-21 탄생", result)
}
})
테스트 코드를 kotest 테스트 레이아웃으로 해도 run icon이 보이지 않는 경우
plugin에서 kotest를 설치해주세요
kotest plugin 설치후 run icon이 보입니다
kotest plugin을 설치하게되면
kotlin파일에서 cmd + shift + t 눌러서 테스트 코드 자동 생성 기능이 있습니다
infix function을 이용한 방법으로 assertion을 수정합니다
internal class DateTimeUtilsTest : StringSpec ({
"DateTimeUtil 출력 검증" {
val result = getLocalDateTimeString(
LocalDateTime.of(2023, 12, 21, 10, 10)
)
result shouldBe "2023-12-21 탄생"
}
})
BehaviorSpec으로 Service 테스트코드 구현
mockk()는 타입에 맞는 mock객체를 만들어줍니다.
typescript로 개발할때 jest를 사용해보신 분들은 jest.fn()와 유사한 경험을 할 수 있습니다
테스트케이스 작성할때 정상 동작 검증, 예외케이스 검증, 실패 검증을 나눠서 합니다
이럴때 Given데이터는 대부분 재사용할 수 있습니다
그러나 jest로 개발할때나 JUnit을 사용할때는 중복코드를 작성했었습니다. 테스트 코드의 Given부분은 함수로 빼지 않았어요.
오히려 함수로 빼면 테스트 코드를 파악하기가 어려웠습니다. 개인차가 있을 수 있습니다.
그런데 Kotest BehaviorSpec을 사용하면 공통 코드를 중복으로 작성하지 않아도 충분히 가독성이 있게 테스트 케이스를 작성할 수 있었습니다.
class PrinceMakerServiceKTest : BehaviorSpec({
var princeRepository: PrinceRepository = mockk()
var woundedPrinceRepository: WoundedPrinceRepository = mockk()
var princeMakerService: PrinceMakerService = PrinceMakerService(princeRepository, woundedPrinceRepository)
Given("프린스 생성 요청이 들어왔을 때") {
var request = CreatePrince.Request(
princeLevel = JUNIOR_PRINCE,
skillType = INTELLECTUAL,
experienceYears = 3,
princeId = "princeId",
name = "name",
age = 38
)
var juniorPrince = PrinceMock.createPrince(
JUNIOR_PRINCE, INTELLECTUAL, PrinceMakerConstant.MAX_JUNIOR_EXPERIENCE_YEARS, "princeId"
)
every { princeRepository.save(any()) } returns juniorPrince
When("id가 중복되지 않고 정상 요청인 경우") {
every {
princeRepository.findByPrinceId(any())
} returns Optional.empty()
Then("정상 응답을 합니다") {
val response = princeMakerService.createPrince(request)
response.princeLevel shouldBe JUNIOR_PRINCE
response.skillType shouldBe INTELLECTUAL
response.experienceYears shouldBe 3
}
}
When("id가 중복되고 정상 요청인 경우") {
every {
princeRepository.findByPrinceId(any())
} returns Optional.of(juniorPrince)
val ex = shouldThrow<PrinceMakerException> {
princeMakerService.createPrince(request)
}
Then("익셉션 발생합니다") {
ex.princeMakerErrorCode shouldBe DUPLICATED_PRINCE_ID
}
}
}
})
테스트 결과도 Given, When, Then으로 중첩되서 보여지기 때문에 가독성이 좋습니다
'스프링 프레임워크 > kotlin' 카테고리의 다른 글
kotlin-springboot spring-kafka로 produce, consume 시작하기 (0) | 2024.08.12 |
---|---|
Java/Spring -> Kotlin/Spring 변환 - 4 (0) | 2024.08.07 |
Java/Spring -> Kotlin/Spring 변환 - 2 (0) | 2024.07.27 |
Java/Spring -> Kotlin/Spring 변환 - 1 (0) | 2024.07.24 |