티스토리 뷰
코프링으로 개발 시 마주친 에러 관련 포스팅입니다.
개발 환경은 다음과 같습니다.
- Spring Boot Version : 3.0.1
- Java Version : 17
- Kotlin Version : 1.8.21
- Kotest Version : 5.5.5
배경
kotest를 사용하는 프로젝트에서 통합 테스트를 위해 @Sql 어노테이션을 사용하여 데이터를 밀어넣어주었습니다.
통합 테스트 관련 내용은 아래 포스팅 참고해주세요.
kotest 중 DescribeSpec을 사용했습니다.
허나, script가 동작되지 않았습니다.
디버깅을 해보니 kotest 내에선 @Sql 어노테이션 자체를 인식하지 못하는 것 같았습니다.
이렇게 추측했던 이유는 JUnit 기반의 똑같은 테스트 코드에서는 잘 동작했기 때문입니다.
확실하진 않지만 제가 원인으로는 다음과 같습니다.
kotest에서 @Sql이 동작하지 않은 이유 - listener
kotest에서는 기본적으로 listener가 동작하지 않는다고 합니다.
허나 @Sql은 SqlScriptsTestExecutionListener에 의해 실행된다고 나와있습니다.
그렇기 때문에 kotest 내부에서 listener를 직접 설정해주지 않으면 @Sql 어노테이션에 설정한 script 파일은 동작하지 않는거죠.
kotest에서 sql script 실행시키기
저는 그래서 @Sql 어노테이션이 아닌 다른 방법을 찾아보았습니다.
kotest에서는 JUnit의 @BeforeEach 같은 기능을 제공해주고 있습니다.
kotest에서는 그 기능을 hooks이라고 칭하고 있습니다.
저는 hooks에서 beforeSpec으로 sql script를 실행시켜주었습니다.
위 링크를 통해서 beforeSpec이 아닌 다른 기능이 필요하시면 참고 부탁드립니다.
package com.laboratorykkoon9.kotlinspring.cafe.service
import com.laboratorykkoon9.kotlinspring.cafe.repository.CafeRepository
import com.laboratorykkoon9.kotlinspring.cafe.service.model.CreateCafeDto
import com.laboratorykkoon9.kotlinspring.cafe.service.model.UpdateCafeDto
import com.laboratorykkoon9.kotlinspring.config.QuerydslConfig
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe
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.core.io.ClassPathResource
import org.springframework.data.domain.Pageable
import org.springframework.jdbc.datasource.init.ScriptUtils
import java.sql.SQLException
import javax.sql.DataSource
@DataJpaTest
@Import(QuerydslConfig::class)
@AutoConfigureTestDatabase(
replace = AutoConfigureTestDatabase.Replace.NONE,
)
internal class CafeServiceTest(
@Autowired private val cafeRepository: CafeRepository,
@Autowired private val dataSource: DataSource,
): DescribeSpec({
beforeSpec {
try {
dataSource.connection.use {conn ->
ScriptUtils.executeSqlScript(
conn,
ClassPathResource("/sql/cafe.sql")
)
}
} catch (e: SQLException) {
throw RuntimeException(e)
}
}
val cafeService = CafeService(cafeRepository)
describe("createCafe") {
context("이미 존재하는 카페 이름으로 생성을 시도하면") {
val cafeDto = CreateCafeDto(
name = "둥겸의 커피집"
)
it("예외를 던진다.") {
shouldThrow<IllegalArgumentException> {
cafeService.createCafe(cafeDto)
}
}
}
}
})
beforeSpec 내부에 dataSource를 사용하여 sql문을 실행시켜주었습니다.
결론
단위 테스트 책을 읽고 통합 테스트는 mock이 아닌 실제 데이터로 테스트하기로 마음먹은 후로 계속해서 시행착오가 있었습니다.
드디어 kotest 내부에서도 통합 테스트를 하는 코드를 그럴싸하게 작성해본 것 같습니다.
추가로, 궁금하신 부분이나 잘못되었다고 생각하는 부분 코멘트 부탁드립니다.
읽어주셔서 감사합니다.
참고 링크
'개발 노트' 카테고리의 다른 글
[스프링+코틀린] API 버저닝 시 bean name conflict 해결 - BeanNameGenerator (0) | 2023.10.31 |
---|---|
[스프링+코틀린] Optional 코틀린스럽게 구하기 - 엘비스 연산자 (2) | 2023.10.18 |
[스프링+코틀린] jdbcSqlSyntaxErrorException column not found (0) | 2023.09.30 |
[스프링+코틀린] mock 없이 통합 테스트하기 (0) | 2023.09.21 |
[스프링+코틀린] H2 Create Table 및 Insert 에러 (0) | 2023.09.21 |
- Total
- Today
- Yesterday
- 디자인패턴
- 객체지향
- BOJ
- 백준
- BAEKJOON
- Spring Boot
- 클린 아키텍처
- Algorithm
- 이펙티브 자바
- 프로그래머스
- 클린 코드
- 코테
- programmers
- Olympiad
- 이팩티브 자바
- C++
- node.js
- 알고리즘
- kkoon9
- Effective Java
- Java
- 정규표현식
- Spring
- kotest
- 디자인 패턴
- AWS
- 테라폼
- MSA
- JPA
- Kotlin
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |