Error resolution

Spring boot 3 JUnit test java.lang.NoSuchMethodError 'parseQualifiedMethodName' 이슈 해결

keepbang 2023. 9. 6. 17:48

 

junit test를 진행할 때 given/when/then 형태로 테스트 작성을 많이 한다.

 

이때 입력 데이터를 다양하게 받고 싶을 때 아래와 같이 사용하곤한다.

  private static Stream<Arguments> testParameter() {
    return Stream.of(
        Arguments.arguments("test", 1, new TestObject(1)),
        Arguments.arguments("test", 2, new TestObject(2))
    );
  }

  @ParameterizedTest
  @MethodSource("testParameter")
  void test(String arg1, Integer arg2, TestObject testObject) {
   ...
  }


이슈 사항

 

 

이번에 Spring boot 3 로 변경하고 ParameterizedTestMethodSource를 사용하여 위와같이 썻는데 에러가 나왔다!

 

'java.lang.String[] org.junit.platform.commons.util.ReflectionUtils.parseQualifiedMethodName(java.lang.String)'
java.lang.NoSuchMethodError: 'java.lang.String[] org.junit.platform.commons.util.ReflectionUtils.parseQualifiedMethodName(java.lang.String)'
Suppressed: org.junit.platform.commons.PreconditionViolationException: Configuration error: You must configure at least one set of arguments for this @ParameterizedTest
        at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:299)
        at org.junit.jupiter.params.ParameterizedTestExtension.lambda$provideTestTemplateInvocationContexts$5(ParameterizedTestExtension.java:98)
        at java.base/java.util.stream.AbstractPipeline.close(AbstractPipeline.java:323)
        ....

에러내용으로 볼 때 parseQualifiedMethodName 이라는 method가 없어서 에러가나오는거같다.

실제로 에러에 출력된 메소드로 들어가보면 해당 메소드가 빨간색으로 표시된다.

MethodArgumentsProvider.java -> getFactoryMethodBySimpleOrQualifiedName

 



해결

일단 해당 메소드는 MethodSource에 아무런 인자를 안넣거나 Argument 메소드를 넣을 때만 발생한다.

 

위에 메소드 위쪽 메소드를 보면 그건 사용 가능한것으로 보여서 그 메소드를 실행하는 곳을 가보니 클래스를 지정해서 사용하면 되는것으로 보인다.

 

메소드의 실행 과정을보면 아래와 같다.

 

getFactoryMethod -> looksLikeAFullyQualifiedMethodName -> getFactoryMethodByFullyQualifiedName

 

1. getFactoryMethod 호출

2. looksLikeAFullyQualifiedMethodName 에서 메소드 이름 확인

3. 메소드 이름에 #이 포함되어있으면 true return

4. getFactoryMethodByFullyQualifiedName 메소드 실행

 

 

getFactoryMethodByFullyQualifiedName 이 메소드를 탈려면 MethodSourceclass path까지 입력해야한다.

 

  private static Stream<Arguments> testParameter() {
    return Stream.of(
        Arguments.arguments("test", 1, new TestObject(1)),
        Arguments.arguments("test", 2, new TestObject(2))
    );
  }

  @ParameterizedTest
  @MethodSource("com.demo.user.dto.UserDtoTest#testParameter")
  void test(String arg1, Integer arg2, TestObject testObject) {
   ...
  }

사용방법은 MethodSource("classPackagePath.className#ParameterMethodName") 이렇게 사용하면 된다.

 

 



원인

원인은 버전문제인듯하다!

 

찾아보니 gradle 버전이 업데이트 되어있고 gradle에서도 이슈로 등록되어 있었다.

 

 

 

8.1 RC 1: Regression in JUnit5 parameterized tests · Issue #24429 · gradle/gradle

Current Behavior Tests with @ParameterizedTest and @MethodSource no longer works, throwing java.lang.NoSuchMethodError: 'java.lang.String[] org.junit.platform.commons.util.ReflectionUtils.parseQual...

github.com

 

프로젝트에 gradle버전을 바꿔봤는데 또 에러가남... 일단 해결 방법을 알았으니 위에 방법대로 해야겠다.

 

나중에 프로젝트만들때에는 처음부터 gradle버전을 최신버전으로 해야할듯싶다.