1. AnnotationSpec의 사용성
AnnotationSpec에서 @Nested를 사용할 수 없다..
- Kotest 5에서 @Nested을 지원한다고 하였지만 https://github.com/kotest/kotest/commit/69eea2d50067c6fa309fbad568d770c5e861a439에서 주석 처리되었다.
- Added support for @Nested in AnnotationSpec
- https://github.com/kotest/kotest/issues/2367
- https://github.com/kotest/kotest/issues/3103
java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...
2. 생성자로 Bean을 주입 받을 수 없는 이슈
Could not create instance of class apply.domain.cheater.CheaterRepositoryTest. Specs must have a public zero-arg constructor.
- 증상
- 코틀린스타일을 상속받고 실행하면, zero-arg constructor(default constructor)가 필요하다.
- 한 편, 기존 코드는 생성자를 통해 Spring Bean을 주입받는다
- @TestConstructor*(*autowireMode = TestConstructor.AutowireMode.*ALL)*
- 이를 해결하려면, Spring Bean을 필드 주입을 통해 입력받을 수도 있으나, 이 방법도 문제가 있음(2번에서 설명)
- 원인
- 해결 방법
- Spring Extension에 대한 의존을 추가한다.
- testImplementation("io.kotest.extensions:kotest-extensions-spring:1.1.1")
3. @Autowired 로 필드 주입을 받을 수 없는 이슈
kotlin.UninitializedPropertyAccessException: lateinit property evaluationTargetRepository has not been initialized
- 증상
- @Autowired 어노테이션을 통해 주입받으려 하는 경우 예외가 발생한다(lateinit 변수가 초기화되지 않았다고 예외를 던진다)
- 원인
- 실행 주체인 kotest가 @Autowired 를 활성화시키지 않는다.
- 해결
- 아래와 같이 명시적으로 전역 설정을 추가해준다.
// ProjectConfig.kt object ProjectConfig : AbstractProjectConfig() { override fun extensions(): List<Extension> = listOf(SpringExtension) }
4. ProjectConfig를 등록하면, 다시 생성자로 주입 받을 수 없는 이슈
java.lang.ClassNotFoundException: kotlinx.coroutines.test.TestDispatcher
- 증상
- 1번과 2번 항목을 반영한 뒤, 다시 테스트를 실행하면 위와 같은 예외가 발생한다.
- 그런데 캐시의 영향인지, 알 수 없는 이유로 ProjectConfig를 제거해도 같은 문제가 발생한다.
- 원인
- 스프링부트에서 설정된 kotlin-coroutines 의 버전이 올바르지 않다.
- kotest에서는 1.6.0 이상을 요구하는데, 스프링에서 가져온 버전은 그 미만이다.
- https://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot-dependencies/build.gradle (987 line)
- 해결
- 따라서 다음과 같이 명시적으로 버전을 지정해야 한다.
- build.gradle.kts 에 다음을 추가한다.
- extra["kotlin-coroutines.version"] = "1.6.0"
- (참고자료) https://github.com/kotest/kotest/issues/2782#issuecomment-1016466398
5. verify 메소드 이슈(올바르게 동작하지 않는다).
- 증상
- mock 객체의 메소드가 몇 번 실행되었는지 확인하는 메소드 verify(exactly = 1) 가 올바르게 동작하지 않는다. (2번 호출되었다는 예외를 던진다)
- 원인
- 테스트가 격리되지 않아서 발생하는 문제. 하나의 클래스에, 서로 다른 테스트 케이스에 해당 메소드를 호출하는 코드가 있었다.
- 매 테스트 실행(메소드 실행)마다 인스턴스를 새로 생성하는 JUnit과 달리, Kotest는 하나의 인스턴스로 모든 테스트를 수행한다.
- 해결
- mock 객체를 @BeforeEach 단계에서 매 번 새로이 초기화하였다. mockkClass(XXX::class
6. mocking 관련 이슈
- @MockK 어노테이션으로 mocking을 할 수 없다.
- 직접 mockk<Class>() 를 해야 한다.
- 이러한 경우 lateinit var 를 사용할 필요가 없으니, val을 사용하자!
- https://kotest.io/docs/framework/integrations/mocking.html
// 기존
@Mockk
lateinit var userRepository: UserRepository
// kotest 적용 후
val userRepository: UserRepository = mockk()
'공부 > Kotlin' 카테고리의 다른 글
코틀린에서 JPA를 사용할 때 고려할 점(SETTER, 생성자 안의 프로퍼티, data class) (3) | 2022.08.28 |
---|---|
코틀린 기본내용을 모두 정리해보자 (2) | 2022.08.27 |
왜 Kotest를 사용해야 할까? (2) | 2022.07.26 |
Kotest의 테스트스타일 10가지 (0) | 2022.07.26 |
11장 DSL 만들기 (0) | 2022.07.18 |
댓글