테스트 코드 shouldBe JUnit? Kotest?

2024. 1. 13. 12:10Technology/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를 저장하는 테스트 코드가 있다고 치자.

 

예시를 위한 코드이니, "MemberService를 테스트하지 않는데?" 라는 말은 삼켜주자

 

여기서 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으로 빠르고 효율적인 작성이 가능해진다.

 

재미있는 Live Template 활용

 

 

아무튼 결국 Kotest로 작성한 테스트 코드들을 JUnit으로 리팩토링 하였다.

하면서 알게 된 꿀팁은 shouldBe, shouldNotBe와 같은 가독성 좋은 Kotest의 fun들은 그대로 가져갈 수 있다는 것.

 

 

사실 이번 글은 이 조합의 아이디어를 자랑하려고 쓴 것이다.🤭

 


 

모든 코드와 개발에는 이유가 있어야 한다.

후에 또 다른 동료가 나와 함께 개발하게 된다면, 테스트 코드가 구성된 이유에 대해 묻는다면, 이 글을 보여주며 재미있게 이야기를 나눠볼 수 있기를.

혹시 알고 있는 다른 방법이 있거나 놓친 것이 있다면 편하게 의견 남겨주시기를 바란다.

 

 

Thanks to Json, Toby!

반응형