인프런 커뮤니티 질문&답변

돌아온무리뉴님의 프로필 이미지

작성한 질문수

실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)

7강. Junit5으로 Spring Boot 테스트하기

AssertionsForInterfaceTypes를 사용하는 이유가 궁금합니다

작성

·

301

1

안녕하세요 강사님!

그동안 테스트 코드를 작성할 땐 Assertj의 Assertions 클래스를 사용해왔는데, 강사님께서는 AssertionsForInterfaceTypes를 사용하시더라구요..!! AssertionsForInterfaceTypes를 특별히 사용하신 이유가 있을까 하여 질문 남겨드립니다.

코드를 살펴보니 Assertions.assertThat이 내부적으로 AssertionsForInterfaceTypes.assertThat을 호출하는 것 같아 보이는데.. 사실 공식문서도 찾아봤는데 이해가 잘 되지 않네요ㅜㅜ

1) AssertionsForInterfaceTypes.assertThat

2) Assertions.assertThat

답변 2

1

돌아온무리뉴님의 프로필 이미지

2022. 08. 15. 21:43

제네릭은 봐도 봐도 헷갈리네요 ㅠㅠ 그래도 예시를 보여주시니 좀 더 이해가 수월한 것 같네요!! 자세한 설명 감사드립니다!!! ㅎㅎㅎ

1

최태현님의 프로필 이미지
최태현
지식공유자

2022. 08. 15. 21:11

안녕하세요, 돌아온무리뉴님~!!!

크으~~ 너무너무 좋은 질문이십니다 ㅎㅎㅎㅎㅎ 감사합니다 ㅎㅎㅎ

 

결론부터 말씀드리자면, 강의 촬영 당시에는 특별한 이유는 없었는데요!!!

돌아온무리뉴님께서 질문을 해주셔서 조금 찾아보니, Assertions.java를 import하거나, AssertionsForClassType.java를 import 하거나, AssertionsForInterfaceType.java를 import 하거나 크게 차이는 없다고 생각되었습니다.

다만, 굳이굳이 (완전 강조입니다!! 정말 minor 하다고 생각해요!) 따지면 AssertionsForInterfaceType.java를 쓰는게 좋겠다 라는 생각이 들었습니다

 

이렇게 생각한 이유는 다음과 같습니다!!!

1. AssertionsForClassType과 AssertionsForInterfaceType은 Generic 에서 타입이 missing 되는 문제로 Class가 나누어져 있습니다!! (이 내용은 두 클래스를 포함해 Assertions.java에도 주석으로 남아 있습니다!)

 

2. 즉, Assertions.java를 import 해서 사용하다보면 다음과 같은 문제가 생길 수 있습니다 (https://stackoverflow.com/questions/29499847/ambiguous-method-in-java-8-why) 실제 Assertions.java 주석에도 런타임 타입 식별 불가 문제가 생기면, 둘 중 하나를 사용하라고 얘기하고 있습니다!

 

3. AssertionsForInterfaceType은 AssertionsForClassType를 상속받고 있습니다! 때문에 AssertionsForInterfaceType를 import 받더라도 Class Type에 대한 assert를 수행하면 AssertionsForClassType의 assert를 사용합니다!

 

4. 반면, AssertionsForClassType을 import 해서 사용하게 되면 다음과 같은 코드는 동작하지 않습니다!

 

(예시 1 - AssertionsForClassType.java 사용)

두 번째 assertThat이 AssertProvider를 구현하고 있음에도 불구하고 object 자체 에 대한 assertThat으로 인식되어 실패한다.

(예시 2 - AssertionsForInterfaceType.java 사용)

두 번째 assertThat이 AssertProvider를 구현하고 있고, AssertionsForInterfaceType에서는 이에 대한 처리를 해주고 있어 정상적으로 통과한다.

 

간단하게 정리드려보면 이렇습니다!

- 우선 Assertions.java는 위에서 언급드린 문제가 생길 '수도' 있으므로 패스한다면 남는 것은 ClassType 과 InterfaceType이다.

- 둘 중 하나를 직접적으로 import해 사용해야 한다면 위의 예시로 봤을 때 InterfaceType이 조금 더 낫다.

 

하지만 당연히 제네릭 타입이 사라지는 문제가 그리 흔하지 않고, AssertProvider<T>를 사용하는 상황이 흔하지도 않습니다!!!

그래서 제가 굳이굳이 라고 강조드렸고요!!!

 

때문에 셋 중 아무거나 import 해주시면 될 것 같습니다 ㅎㅎㅎㅎㅎ 강의에서는 테스트를 처음 접하시는 분들이 타겟이다 보니 low-level 설명을 드리기는 어려워, import 잘 해주세요~ 느낌으로만 넘어간 것도 있습니다 ㅎㅎㅎㅎ

 

아이고~~ 또 이렇게 돌아온무리뉴님께서 좋은 질문 남겨주셔서 저도 하나 배워가네요~~!!

감사합니다!!! 연휴 마지막 밤 편안한 시간 되세요~!!! 🙇