[Java] record class Mocking 에러 해결하기
2022. 12. 2. 03:13ㆍJava/Basic
반응형
record class로 작성된 Notice 객체를 모킹하려고 할때
public record NoticeDetail(long id, String title, String content, String createdAt) { }
class GetNoticeServiceTest { private final LoadNoticePort loadNoticePort = Mockito.mock(LoadNoticePort.class); @Test void getNotice() { Notice notice = givenNoticeWithId(1L); System.out.println(notice); } private Notice givenNoticeWithId(Long id) { Notice notice = Mockito.mock(Notice.class); given(notice.id()).willReturn(id); given(loadNoticePort.loadNotice(id)).willReturn(notice); return notice; } }
아래와 같은 에러가 발생됩니다.
Cannot mock/spy class com.chaeking.api.notice.domain.Notice Mockito cannot mock/spy because : - final class org.mockito.exceptions.base.MockitoException: Cannot mock/spy class com.chaeking.api.notice.domain.Notice Mockito cannot mock/spy because : - final class at app//com.chaeking.api.notice.application.service.GetNoticeServiceTest.givenNoticeWithId(GetNoticeServiceTest.java:23) at app//com.chaeking.api.notice.application.service.GetNoticeServiceTest.getNotice(GetNoticeServiceTest.java:18) at java.base@17.0.4.1/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.4.1/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.4.1/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.4.1/java.lang.reflect.Method.invoke(Method.java:568) at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
기본적으로 Mockito 는 final class를 모킹할 수 없는데,
record class는 불변 데이터 객체이기 때문에 모킹이 되지 않는 것입니다.
해결책 1. final을 붙이지 않은 클래스로 변경하기
Notice 클래스를 final을 붙이지 않은 일반 클래스로 변경합니다.
@AllArgsConstructor @Data public class Notice { private Long id; private String title; private String content; private LocalDateTime createdAt; }
class GetNoticeServiceTest { private final LoadNoticePort loadNoticePort = Mockito.mock(LoadNoticePort.class); @Test void getNotice() { Notice notice = givenNoticeWithId(1L); System.out.println(notice); } private Notice givenNoticeWithId(Long id) { Notice notice = Mockito.mock(Notice.class); given(notice.getId()).willReturn(id); given(loadNoticePort.loadNotice(id)).willReturn(notice); return notice; } }
일반 클래스로 변경하니 아래와 같이 모킹이 정상적으로 작동되었습니다.
> Task :chaeking-api-hexagon:compileJava UP-TO-DATE > Task :chaeking-api-hexagon:processResources UP-TO-DATE > Task :chaeking-api-hexagon:classes UP-TO-DATE > Task :chaeking-api-hexagon:compileTestJava > Task :chaeking-api-hexagon:processTestResources UP-TO-DATE > Task :chaeking-api-hexagon:testClasses > Task :chaeking-api-hexagon:test Mock for Notice, hashCode: 1227459815 BUILD SUCCESSFUL in 931ms 5 actionable tasks: 2 executed, 3 up-to-date 3:00:03 AM: Execution finished ':chaeking-api-hexagon:test --tests "com.chaeking.api.notice.application.service.GetNoticeServiceTest.getNotice"'.
해결책 2. Mockito inline 의존성을 추가하기
final class, final method, static method의 모킹을 지원해주는 Mockito inline 의존성을 추가해주면 기존 코드가 정상적으로 돌아갑니다.
testImplementation("org.mockito:mockito-inline:4.9.0")
위의 의존성을 추가하면, Notice 클래스를 record 클래스로 둬도 모킹이 정상적으로 잘 동작됩니다.
> Task :chaeking-api-hexagon:compileJava UP-TO-DATE > Task :chaeking-api-hexagon:processResources UP-TO-DATE > Task :chaeking-api-hexagon:classes UP-TO-DATE > Task :chaeking-api-hexagon:compileTestJava UP-TO-DATE > Task :chaeking-api-hexagon:processTestResources UP-TO-DATE > Task :chaeking-api-hexagon:testClasses UP-TO-DATE > Task :chaeking-api-hexagon:test OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended Mock for Notice, hashCode: 184244257 BUILD SUCCESSFUL in 1s 5 actionable tasks: 1 executed, 4 up-to-date 3:04:00 AM: Execution finished ':chaeking-api-hexagon:test --tests "com.chaeking.api.notice.application.service.GetNoticeServiceTest"'.
++
- how to mock a record class
- record class 모킹하기
- final class 모킹하기
728x90
반응형
'Java > Basic' 카테고리의 다른 글
[Java] override, overload (1) | 2023.02.05 |
---|---|
[Java] Functional Programming - 1. Java 함수형 프로그래밍의 개요와 Stream (1) | 2022.12.08 |
[JCA] HMAC을 이용한 API Request 변조 검증 (0) | 2022.07.29 |
[JCA] Hash 함수의 개요와 PBKDF2를 이용한 단방향 해시 알고리즘 구현 (2) | 2022.07.27 |
[JCA] Cipher 클래스를 이용한 AES 대칭키 암복호화 (0) | 2022.07.22 |