java.lang.Exception: No runnable method 오류 해결법

728x90

 

테스트 코드를 실행하는데 다른 테스트코드는 괜찮았는데 저 테스트 클래스만 JUnit Vintage라는 오류가 발생했다. 이 문제를 해결해보고자 구글링을 해보았다. 먼저 JUnit5를 잘못 사용한 것이 아닌가? 하는 의심이 들었다.(실은 크게 잘못 사용할만한 부분이 없었다) 테스트코드에 대한 기초지식도 없었을 때, Junit5는 JUnit Vintage + JUnit Jupiter이다라고 하면서 공부했던 적이있는데, 어쨋거나 jUnit5의 두 요소중 하나의 요소만 테스트에 성공했으니 junit Vintage의 요소를 제대로 못받아 온게 아닌가... 즉 의존성 설정부분에서 실수한 것이 있을 것 같다는 생각이 들었다. 아래의 링크를 참조해서 설정을 해보았다. 

https://flyburi.com/607 

 

[Junit5] SpringBoot2+Junit5 에서 TestEngine with ID 'junit-jupiter' failed to discover tests 오류 해결방법

Spring Boot 의 기본 junit4 대신 junit5(2019.7월 말 현재 최신버전인 junit 5.5.1 )를 쓰기 위해 설정하는 도중 만난 오류가 있어서 공유합니다. 개발 환경 IngelliJ IDEA gradle 5.0 Spring Boot 2.1.0.RELEASE..

flyburi.com

 

위와 같이 의존성을 추가적으로 설정했다. 윗 글의 필자에 의하면 어떤 오류가 발생한다고 하는데, 나는 이전에 발생했던 오류가 동일하게 발생했다. 분명 이전까지 잘 돌아가던 테스트 코드이기도 했고, 의존성 변경에도 변화가 없는걸로 보아, 이 방법은 해결방법이 아니라고 생각하였다. 

https://larva.tistory.com/entry/spring-boot-javalangException-No-runnable-methods

 

 

[spring boot] java.lang.Exception: No runnable methods

spring boot로 테스트 실행시 아래와 같이 예와가 난다. ---------------------------------------------------------------------------------------------------------------------------- java.lang.Exception:..

larva.tistory.com

위 글은 테스트 메서드에 @Test 를 안붙여서 나와 같은 오류가 발생했다고 하는데, 나는 분명 모든 테스트 메서드를 @Test 어노테이션을 붙였다. 이 오류 케이스도 나의 문제가 아니였다. 


의외로 이 오류가 발생한 원인은 간단했다. 제대로 동작하는 다른 테스트 코드들이랑 처음부터 비교해봤더니 오류가 발생하는 테스트 클래스에 'public' (접근자)이 붙어있다는 차이점이 있었다. 이유는 잘 모르겠지만 일단 다른 테스트 클래스처럼 public을 지우고 테스트를 실행해보았다. 

그랬더니 앞서 발생했던 오류도 없어졌다. (아예 테스트 실행창에 JUnit Vintage, JUnit Jupite로 구분되서 출력되지도 않는다)  https://effectiveprogramming.tistory.com/entry/package-private-class%EC%97%90-%EB%8C%80%ED%95%9C-unit-test-%EB%B0%A9%EB%B2%95

 

package private class에 대한 unit test 방법

설계를 하다보면 종종 상위의 인터페이스나 상위 클래스는 외부에 public으로 노출을 시키되, 하위의 구체 클래스들은 외부에 노출시키지 않아야 하는 경우가 있다. 이는 정보 은닉을 위한 좋은 설계 방법 중 하나..

effectiveprogramming.tistory.com

뭔가 직접적인 이유라고 하기에는 뭐하지만 위의 내용을 참조하면 좋은 것 같다. 내용을 조금 인용해보자면 다음과 같다. 

더보기

설계를 하다보면 종종 상위의 인터페이스나 상위 클래스는 외부에 public으로 노출을 시키되, 하위의 구체 클래스들은 외부에 노출시키지 않아야 하는 경우가 있다. 이는 정보 은닉을 위한 좋은 설계 방법 중 하나이다. 이를 위해서 보통 하위의 구체 클래스들을 package private class(JAVA에서 접근자 키워드가 없이 선언되는 클래스)로 선언한다. 이렇게 하면 같은 패키지 내에서는 해당 클래스에 접근할 수 있어도 다른 패키지에서는 package private 클래스를 접근할 수 없으므로 오직 인터페이스나 상위 클래스를 이용할 수 밖에 없다. 따라서 하위 클래스들의 변경이나 추가와 같은 유연성이 보장된다.

하지만 문제는 package private class에 대한 Unit Test를 작성하는 일은 쉽지 않다는 점이다. 일반적으로 제품 코드와 유닛 테스트 코드는 분리되는 것이 좋다. 제품 코드와 유닛 테스트 코드가 같은 곳, 즉 같은 패키지 내에 존재하면 제품의 출시를 위해서 유닛 테스트 코드를 골라내는 작업이 필요하다. 또 제품 코드를 이해하기 위해서 소스를 뒤적이다 보면 유닛 테스트 코드가 함께 섞여 있어서 불편함을 겪게 된다. 그래서 일반적으로 제품 코드와 유닛 테스트 코드를 분리하여 두는데, 이렇게 되면 제품 코드와 유닛 테스트 코드의 패키지가 분리되면서 package private인 요소들에 대해서는 유닛 테스트가 접근할 수 없게 된다. 이렇게 되면 간접적으로 해당 요소들을 테스트해야 하는데 이는 매우 번거로운 작업이 된다.

 


https://www.crocus.co.kr/1665

 

[JUnit] private 메서드, 변수 테스트 방법

JUnit으로 유닛 테스트를 하다보면 Method 테스트, Class 단위 테스트, 혹은 Module 단위의 테스트를 하게 된다. 하지만 Class, Module 단위처럼 큰 범위로 가게 되면 테스트하기 조금 어렵거나 까다로운 것들이..

www.crocus.co.kr

오류에 관련된 포스팅들을 보다가 제목이 눈에 끌려서 보게되었다. 테스트 코드를 작성할 때, 캡슐화를 하다보니면 private method, private variable이 존재하게 되는데... 이 메서드나 변수를 테스트할 때, 사용할 수 없어서 어떻게 테스트를 해야하는지에 대한 고민들이 많았다. (내가 조언받은 방법으로는 더 많이 코드를 쪼개서 역할을 분담하므로서 public 인자로 바꿔가는 것이었다) 

이 방법이 좋은지에 대해서는 확신은 못하겠지만, "이런 방법도 있구나?" 정도로 생각하면 좋을 것 같다. 

728x90