NullPointException 부근 질문있습니다.
973
작성한 질문수 4
test의 경우 EventRepository에 save를 하고 난 값이 리턴되지 않기 때문에 Mockito를 이용해서 객체를 그대로 리턴해주는 식으로 이해했습니다. 그런데 이 부분에서 똑같이 NPE가 발생하길래 왜 그런가 봤더니 Event 엔티티의 @EqualsAndHashCode 사용 유무 문제였습니다.
여기서 의문이 드는게 @EqualsAndHashCode가 Mockito의 리턴이랑 무슨 관계인지 이해가 안갑니다. 단순히 Test에서 만든 Event 객체를 다시 리턴시키는데 왜 @EqualsAndHashCode가 영향을 미치는 건가요??
답변 14
4
오 생각보다 복잡한 이슈였네요.
Mockito.when(eventRepository.save(event)).thenReturn(event);
여기 보시면 save에 넘겨주는 event가 있고 그 객체가 넘어오면 event를 리턴하라고 스터빙을 한건데요.
@EAH가 없으면 여기서 목킹하면서 save에 넘겨주는 event 객체랑 컨트롤러 안에서 save 호출할 때 넘겨주는 event 객체랑..
Event newEvent = this.eventRepository.save(event);
서로 다르다고 생각해서 stubbing을 제대로 적용 안하고 (즉 리턴하라고 했던 event)를 넘겨주지 않고.. 그냥 null이 리턴 됩니다. 그래서 newEvent가 null이 되요.
URI createdURi = linkTo(EventController.class).slash(newEvent.getId()).toUri();
그 상태에서 바로 아래 줄인 저기서 getId를 null에다가 호출하니까 NPE가 발생한겁니다.
@EAH를 사용하시거나, equals랑 hashCode를 직접 구현해서 목킹할 때 넘겨준 객체랑 실제 객체가 같은지 확인 될 수 있게끔 해주시거나..
아니면 테스트 코드를 이렇게 바꿔주시면 아무런 Event 타입의 객체만 받아도 항상 event 객체를 리턴하도록 했기 때문에 @EAH가 없어도 테스트는 잘 동작할 겁니다.
Mockito.when(eventRepository.save(any(Event.class))).thenReturn(event);
0
와 한번에 이해한 것 같습니다.
정리하자면 Mockito에서 when()이 일반적인 이벤트리스너 함수처럼 호출되는 메소드만 같다고 작동하는 것이 아니라 실제로 매개변수에 들어가는 객체까지 같아야 작동하는 것이군요..! 그렇기 때문에 객체를 비교하는 equals()와 hashCode()가 필요한거구요!
바쁘신데 명쾌하고 빠른 답변 정말 감사합니다!
0
넵. 확인해주시기 쉽게 최대한 같은 코드로 올렸습니다.
github : https://github.com/tj3828/RestAPI-NPE
Error :
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:182)
at com.example.npe.events.EventControllerTest.createBoard(EventControllerTest.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NullPointerException
at com.example.npe.events.EventController.createEvent(EventController.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
... 48 more
0
5분 30초 부근입니다.
test가 아닌 실제 서버에서는 상관없는데,
test의 경우에만 Event에 @EqualsAndHashCode가 없으면 여전히 NPE가 발생합니다.
이 상황을 보면, Mokito의 thenReturn 메소드가 @EqualsAndHashCode와 연관이 있는 것 같다고 생각하는데 그 이유를 모르겠어서 질문드렸습니다.
Spring 시큐리티 관련해서 WebSecurityConfigurationAdapter
0
73
1
junit5 사용하시는 분들
0
88
1
자바 빈 스펙을 준수하는지 체크하는 테스트
0
238
2
REST API 개발 중 비즈니스 로직 적용 부분의 JSON 에러
0
243
1
스프링 부트 3버전에서의 실습
0
190
1
java.lang.AssertionError: Status
0
532
2
spring doc 관련 파일 생성 관련 배포 관련 질문 드립니다.
0
287
1
섹션2 201응답받기 부분 테스트 404에러 질문입니다
0
741
1
강의 자료가 404입니다 확인 부탁 드려요!
0
477
1
연동 DB문의
0
358
1
이벤트 Repository강의 중 Event 클래스에 private Integer Id; 위치 질문
0
505
1
(Mac) postgressql 관련하여 port kill 해도 다시 살아나는 경우
0
380
0
maven으로 생성한 docs파일(index.html)에서의 not found 오류 질문
0
621
1
테스트 오류 질문드립니다.
0
512
1
docs 요청값이 반영이 안되네요... (해결)
-1
394
1
psql 적용 후 에러
0
819
2
mvn package 시 다음과 같은 에러가 나시면
0
765
2
Event에 Account manager를 추가했으면 문서화 필요
0
274
1
2년 훨씬 전 부터 Restlet-> Talend API 로 바뀌었습니다~
1
473
1
asciidoc 추가 스니펫 에러 해결법
0
400
1
_links 는 현재 fieldWithPath 를 해주지 않아도 됩니다.
0
424
3
깃랩 처음 사용자를 위한 index.adoc raw 보는 법
0
332
1
eclipse 쓰시는 분을 위한 maven-resources-plugin 팁
0
333
1
부트 + jupiter 인 경우 설정법
0
342
1





