본문 바로가기

Programing/Framework

[Spring] Boot update 3.3.4 to 3.3.5, MethodArgumentTypeMismatchException 변경 사항 확인 by 테스트 코드

지난 주 스프링 부트 버전 업데이트를 진행했다.

스프링 부트 버전 변화에 따라 스프링 프레임워크 버전도 업데이트가 되었다.

  • spring boot 3.3.4: spring framework 6.1.13
  • spring boot 3.3.5: spring framework 6.1.14

프레임워크의 기능을 테스트할 때를 알기

Zarar의 블로그에 좋은 소프트웨어 개발 습관들(Good software development habits)이라는 글을 본 적이 있다.
GeekNews에  "프레임워크의 기능에 대한 테스트를 하지 않기"로 변역이 되어 있어서 무조건 프레임워크의 기능을 테스트하지 말자로 들릴 수 있다. 하지만 나는 "프레임워크의 기능을 테스트할 때와 하지 말 때를 알자"로 해석했다.

Know when you're testing the framework's capability. If you are, don't do it. The framework is already tested by people who know a lot more than you, and you have to trust them that the  useState() hook does what it's supposed to do. 
프레임워크의 기능(자체)을 테스트할 때는 알야야 한다. 만약 그렇다면 하지 말자. 프레임워크는 이미 많은 사람들에 의해 검증되었고 useState() 훅이 제대로 작동한다는 것을 믿어야 한다.

 

GeekNew에 하단에 Hacker New의 프레임워크는 시간이 지나면서 변할 수 있고, 의존성을 업그레이드 할 때 안전한지 확인하는 것이 테스트의 역할이라는 의견이 있었다.

깨지는 테스트 코드

스프링 부트 버전을 3.3.5로 업데이트 후 깨지는 테스트가 있었다.

에러 처리기에서 반환하는 메시지였는데 기대하는 문자열과 실제 반환한 메시지가 서로 달랐기 때문이다.

  • 기대: Failed to convert value of type 'java.lang.String' to required type 'long'; For input string: "string-file-id"
  • 반환: Method parameter 'fileId': Failed to convert value of type 'java.lang.String' to required type 'long'; For input string: "string-file-id"

Root Cause 찾기

원인을 찾기 위해서는 스프링 부트가 의존하는 변화한 스프링 프레임워크의 변화를 확인해야 했다.

찾아보니 MethodArgumentTypeMismatchException 클래스의 구현이 바뀌었다.

6.1.14부터 java.lang.Throwable의 getMessage()를 오버라이드하는 부분이 추가되었다.

 

이전에는 getMessage() 메서드를 오버라이드를 하고 있지 않아서 Throwable가 기본으로 구현한 동작으로 에러 메시지를 반환했다.

하지만 6.1.14부터 앞에 "Method parameter ..." 부분으로 메시지를 표현하도록 변경이 되었다.

 

관련한 스프링 프레임워크의 이슈와 PR은 아래와 같다.

에러 메시지를 애플리케이션에서 직접 외부로 노출을 하고 있지는 않아서 테스트 코드 수정으로 끝났다.
하지만 만약 프레임워크에 메시지에 대한 그대로 의존하고 있다면 애플리케이션의 동작을 바꿀 수도 있는 부분이다.

 

프레임워크에 대한 테스트가 있으면 업데이트시 영향도에 대해 알고 진행할 수 있어서 레거시 코드를 없애는데 도움이 되었다고 생각한다.

To me, legacy code is simply code without tests.
내게 레거시 코드란, 단순히 테스트 루틴이 없는 코드다.
- Working effectively with legacy code(레거시 코드 활용 전략) by Michael C. Feathers.(마이클 페더스)