I have table of users as shown:
Rest controller method for delete user is:
@RequestMapping(APP_USER_API_PATH)
@RestController
@RequiredArgsConstructor
public class AppUserControllerImpl implements AppUserController {
@NonNull
private final AppUserService appUserService;
@NonNull
private final AppUserMapper appUserMapper;
@Override
@DeleteMapping("/{id}")
public ResponseEntity<?> delete(@PathVariable("id") Long id) {
if(appUserService.findById(id).isEmpty())
throw new EntityNotFoundException(String.format("Record not found with id = %s", id));
// If Found then
appUserService.deleteById(id);
return ResponseEntity.status(HttpStatus.OK).body(
String.format("Record with id = %s deleted", id)
);
}
}
Test class and method is as follows:
@SpringBootTest
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
public class AppUserControllerImplTest {
private static final String ENDPOINT_URL = APP_USER_API_PATH;
@InjectMocks
private AppUserControllerImpl appuserController;
@Mock
private AppUserService appuserService;
@Mock
private AppUserMapper appuserMapper;
@Autowired
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(this.appuserController).build();
}
@Test
public void delete() throws Exception {
Mockito.doNothing().when(appuserService).deleteById(ArgumentMatchers.anyLong());
mockMvc.perform(
MockMvcRequestBuilders.delete(ENDPOINT_URL "/" 1L ""))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(appuserService, Mockito.times(1)).deleteById(Mockito.anyLong());
Mockito.verifyNoMoreInteractions(appuserService);
}
}
it always throws exception:
Caused by: javax.persistence.EntityNotFoundException: Record not found with id = 1
and the test always fails even if record with id = 1 exists.
Full StackTrace:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.EntityNotFoundException: Record not found with id = 1
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:931)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:201)
at pk.team.inlab.web.app.profile2.controller.impl.AppUserControllerImplTest.delete(AppUserControllerImplTest.java:141)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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:366)
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$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
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$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
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:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: javax.persistence.EntityNotFoundException: Record not found with id = 1
at pk.team.inlab.web.app.profile2.controller.impl.AppUserControllerImpl.delete(AppUserControllerImpl.java:89)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
... 43 more
CodePudding user response:
The issue is happening because you have not mocked the findById method of AppUserService class
You have written the following piece of code
if(appUserService.findById(id).isEmpty()) throw new EntityNotFoundException(String.format("Record not found with id = %s", id));
which throws as exception if the item with this id is not found.
In the test class, you have mocked the AppUserService using
@Mock
private AppUserService appuserService;
however, you have not told the Mock framework what to do when the findById method is called. Add a Mockito.when statement to your test case for example in the following format
Mockito.when(appUserService.findById(ArgumentMatchers.anyLong())).thenReturn("***Return a dummy object here ***")
This should let the mock framework know that it should return the dummy result when this method is called and that should prevent the exception from being thrown.