2024. 1. 13. 12:10ㆍTechnology/Spring Boot
Kotlin + Spring Boot 조합으로 새 프로젝트를 시작했다.
Jason(작은 재성)님이 이 소식을 듣고 Kotest를 추천해 주셔서, Toby님과 적극적으로 도입하여 활용하기 시작했다.
Kotest에는 여러가지 테스팅 스타일이 있는데, 중첩이 가능한 context와 명시적으로 기대하는 바를 서술할 수 있는 expect가 있는 ExpectSpec을 선택하여 사용했다. Kotest의 Original 이기도 하고.😌
이 외에 다른 Kotest의 Testing Styles는 아래 링크를 통해 확인할 수 있다.
https://kotest.io/docs/framework/testing-styles.html
예시로 Member를 저장하는 테스트 코드가 있다고 치자.
여기서 save()라는 하나의 테스트 단위에 @Transactional(readOnly = true)를 붙여서 에러를 내고 싶은 니즈가 있다고 가정해 보자.
가능한 위치는 class 레벨과 method 레벨이 있다. 근데 method 레벨에 달고 싶으면 Kotest 스타일에서는 어디에 달아야 할까?
보다시피 @Transactional의 Target은 TYPE, METHOD 2가지이다.
그럼 expect method가 시작된다고 볼 수 있는 위치에 달아볼까?
잘 돌아갈 것처럼 달린다.
하지만 결과는 기대한 에러가 나지 않으면서 성공해 버린다.
기대했던 IllegalStateException.
결론은 class 레벨에 붙여주지 않으면 동작하지 않는다는 것이다.
이 실험을 하게 된 이유는 원래 Api 테스트에서 테스트 단위별 @WithMockUser를 사용하고 싶어서였다.
하지만 Kotest 팀의 답변은 "Class 레벨에 붙여."로 closed.
https://github.com/kotest/kotest/issues/337
Kotlin test and spring: WithMockUser · Issue #337 · kotest/kotest
Hello, I'd like to know if it's possible to use the WithMockUser feature of Spring Security test. Thanks beforehand
github.com
뭐, 직접 @WithMockUser가 동작하는 로직을 코드레벨에 구현하라고 하는 사람도 있을 것이다.
나는 Spring이 제공하는 좋은 기능이 있는데 조금 더 우아한 가독성을 위해서 이를 포기하는 게 효율적인지 되물을 것이다.
JUnit으로도 우아한 가독성은 만들 수 있다.
특히 코드 작성할 때 Live Template으로 빠르고 효율적인 작성이 가능해진다.
아무튼 결국 Kotest로 작성한 테스트 코드들을 JUnit으로 리팩토링 하였다.
하면서 알게 된 꿀팁은 shouldBe, shouldNotBe와 같은 가독성 좋은 Kotest의 fun들은 그대로 가져갈 수 있다는 것.
사실 이번 글은 이 조합의 아이디어를 자랑하려고 쓴 것이다.🤭
모든 코드와 개발에는 이유가 있어야 한다.
후에 또 다른 동료가 나와 함께 개발하게 된다면, 테스트 코드가 구성된 이유에 대해 묻는다면, 이 글을 보여주며 재미있게 이야기를 나눠볼 수 있기를.
혹시 알고 있는 다른 방법이 있거나 놓친 것이 있다면 편하게 의견 남겨주시기를 바란다.
Thanks to Json, Toby!