I am trying to test a Spring Controller using Mockito. I have mocked the object also used when() as per this question , but I am still facing the null pointer exception. Please suggest a way to solve this exception.
Github repository of this project
The particular line null pointer linked to is
modelMap.put("categories", simpleCategoryDAO.getAllCategories());
I have mocked simpleCategoryDAO and used when() to return a list for getAllCategories().
Test Method:
#RunWith(MockitoJUnitRunner.class)
public class CategoryControllerTest {
private MockMvc mockMvc;
#InjectMocks
private CategoryController categoryController;
#Mock
private SimpleCategoryDAO simpleCategoryDAO;
#Before
public void setup() {
categoryController = new CategoryController();
mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build();
}
#Test
public void categories_ShouldRenderCategoriesView() throws Exception {
List<Category> ALL_CATEGORIES = Arrays.asList(
new Category(1,"Funny"),
new Category(2,"JoyFul")
);
Mockito.when(simpleCategoryDAO.getAllCategories()).thenReturn(ALL_CATEGORIES);
mockMvc.perform(get("/categories"))
//.andExpect((MockMvcResultMatchers.model()).attribute("categories",ALL_CATEGORIES));
.andExpect(MockMvcResultMatchers.view().name("categories"));
}
}
Code of controller
#Controller
public class CategoryController {
#Autowired
SimpleCategoryDAO simpleCategoryDAO;
#Autowired
SimpleGifDAO simpleGifDAO;
#RequestMapping("/categories")
public String getAllCategories(ModelMap modelMap) {
modelMap.put("categories", simpleCategoryDAO.getAllCategories());
return "categories";
}
#RequestMapping("/category/{categoryID}")
public String getGifsByCategoryID(#PathVariable int categoryID,ModelMap modelMap){
modelMap.put("gifs", simpleGifDAO.findGifsByCategoryID(categoryID));
modelMap.put("category",simpleCategoryDAO.getCategoryByID(categoryID));
return "category";
}
}
Exception:
java.lang.NullPointerException: null
at com.teja.controller.CategoryController.getAllCategories(CategoryController.java:23) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat-embed-core-8.0.23.jar:8.0.23]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.0.23.jar:8.0.23]
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at CategoryControllerTest.categories_ShouldRenderCategoriesView(CategoryControllerTest.java:46) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) [mockito-core-1.10.19.jar:na]
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) [mockito-core-1.10.19.jar:na]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
The problem is on your test class Before method you are instantiating new controller
#Before
public void setup() {
categoryController = new CategoryController();
mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build();
}
Here is how I do test for Controller
Controller Class :
#Controller
public class CategoryController {
private SimpleCategoryDAO simpleCategoryDAO;
private SimpleGifDAO simpleGifDAO;
#Autowired
public void setSimpleGifDAO(SimpleGifDAO simpleGifDAO) {
this.simpleGifDAO = simpleGifDAO;
}
#Autowired
public void setSimpleCategoryDAO(SimpleCategoryDAO simpleCategoryDAO) {
this.simpleCategoryDAO = simpleCategoryDAO;
}
#RequestMapping("/categories")
public String getAllCategories(ModelMap modelMap) {
modelMap.put("categories", simpleCategoryDAO.getAllCategories());
return "categories";
}
#RequestMapping("/category/{categoryID}")
public String getGifsByCategoryID(#PathVariable int categoryID, ModelMap modelMap) {
modelMap.put("gifs", simpleGifDAO.findGifsByCategoryID(categoryID));
modelMap.put("category", simpleCategoryDAO.getCategoryByID(categoryID));
return "category";
}
}
Notice I'm using setter injection here not field injection. You can also use constructor injection ( preferred way for me).
In you test class
#RunWith(MockitoJUnitRunner.class)
public class CategoryControllerTest {
private MockMvc mockMvc;
#Mock
private SimpleCategoryDAO simpleCategoryDAO;
#Before
public void setup() {
final CategoryController categoryController = new CategoryController();
//notice here I'm setting the mocked dao here
// if you didn't use #RunWith(MockitoJUnitRunner.class)
// you can do: simpleCategoryDAO = Mockito.mock(SimpleCategoryDAO.class);
categoryController.setSimpleCategoryDAO(simpleCategoryDAO);
mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build();
}
#Test
public void categories_ShouldRenderCategoriesView() throws Exception {
List<Category> ALL_CATEGORIES = Arrays.asList(
new Category(1, "Funny"),
new Category(2, "JoyFul")
);
Mockito.when(simpleCategoryDAO.getAllCategories()).thenReturn(ALL_CATEGORIES);
mockMvc.perform(get("/categories"))
//.andExpect((MockMvcResultMatchers.model()).attribute("categories",ALL_CATEGORIES));
.andExpect(MockMvcResultMatchers.view().name("categories"));
}
}
Take a look at Before method on test. I'm setting the mocked DAO on the new instance of controller that I've created and then I'm creating the MockMvc using same instance of controller.
I had some issues with the provided solution so I thought I'd share how I solved it. My issue was that when the controller called a method on the DAO it was throwing NullPointerException, because I didn't want to use setter injection to provide the mocked DAO to the controller (I refused to create a setter method in the DAO just to be able to test everything).
Basically for the OP it would require:
NOT instantiating the controller in the setup() method (like Aman pointed out)
Declaring the DAO with the #Mock annotation before the controller declaration.
Like so:
#RunWith(MockitoJUnitRunner.class)
public class CategoryControllerTest {
private MockMvc mockMvc;
#Mock
private SimpleCategoryDAO simpleCategoryDAO;
#InjectMocks
private CategoryController categoryController;
#Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build();
}
#Test
public void categories_ShouldRenderCategoriesView() throws Exception {
List<Category> ALL_CATEGORIES = Arrays.asList(
new Category(1,"Funny"),
new Category(2,"JoyFul")
);
Mockito.when(simpleCategoryDAO.getAllCategories()).thenReturn(ALL_CATEGORIES);
mockMvc.perform(get("/categories"))
//.andExpect((MockMvcResultMatchers.model()).attribute("categories",ALL_CATEGORIES));
.andExpect(MockMvcResultMatchers.view().name("categories"));
}
}
Related
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
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.
I am trying to write a test for a method that throws custom exception. It fails with Assertion error. What could be done to properly catch the exception and pass the test?
Service method:
#Service
public class CustomServiceImpl implements CustomService {
#Autowired
UserUtil userUtil;
public ResultDTO getResultDto (String type, Long id) throws CustomException {
User user = userUtil.getCurrentUser();
if (user == null) {
throw new CustomException("User does not exist");
}
}
}
Test method:
#MockBean
CustomServiceImpl customServiceImpl ;
#Test
public void test01_getResultDto() {
UserUtil userUtil = Mockito.mock(UserUtil.class);
Mockito.when(userUtil.getCurrentUser()).thenReturn(null);
Assertions.assertThatThrownBy(() -> customServiceImpl.getResultDto (Mockito.anyString(), Mockito.anyLong()))
.isInstanceOf(CustomException .class)
.hasMessage("User does not exist");
}
This test fails with the following error:
java.lang.AssertionError: Expecting code to raise a throwable.
at com.ps.service.CustomServiceImplTest.test01_getResultDto(CustomServiceImplTest.java:62)
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.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:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
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:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
--------------------------- EDIT ------------------------
Changed the code Test to include the following
#Mock
UserUtil userUtil;
#InjectMocks
CustomServiceImpl cutomServiceImpl;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void test01_getResultDto() {
when(userUtil.getCurrentUser()).thenReturn(null);
assertThatThrownBy(() -> customServiceImpl.getResultDto ("type", 1L))
.isInstanceOf(CustomException .class)
.hasMessage("User does not exist");
}
Seems to be working.
Thanks to the advice in comments.
I have made suitable changes to my original code and the following set up works well.
#Mock
UserUtil userUtil;
#InjectMocks
CustomServiceImpl cutomServiceImpl;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void test01_getResultDto() {
when(userUtil.getCurrentUser()).thenReturn(null);
assertThatThrownBy(() -> customServiceImpl.getResultDto ("type", 1L))
.isInstanceOf(CustomException .class)
.hasMessage("User does not exist");
}
Another way you can do it is :
#MockBean
CustomServiceImpl customServiceImpl ;
#Rule
public ExpectedException exceptionRule = ExpectedException.none();
#Test
public void test01_getResultDto() {
exceptionRule.expect(CustomException.class);
UserUtil userUtil = Mockito.mock(UserUtil.class);
Mockito.when(userUtil.getCurrentUser()).thenReturn(null);
customServiceImpl.getResultDto ("type", 1L);
}
I have an issue running Controller Tests with CompletableFeature,
I create a StockController!
#Component
public class StockController implements StockResource {
private UseCaseExecutor useCaseExecutor;
private GetAllStocksUseCase getAllStocksUseCase;
#Autowired
public StockController(UseCaseExecutor useCaseExecutor,
GetAllStocksUseCase getAllStocksUseCase) {
this.useCaseExecutor = useCaseExecutor;
this.getAllStocksUseCase = getAllStocksUseCase;
}
#Override
public CompletableFuture<List<StockResponse>> getAllStocks(
#RequestParam(value="materialNumber", required=false) String materialNumber,
#RequestParam(value="storageLocation", required=false) String storageLocation,
#RequestParam(value="plant", required=false) String plant) {
return useCaseExecutor.execute(
getAllStocksUseCase,
GetAllStocksInputMapper.map(
materialNumber,
storageLocation,
plant
),
(outputValues) -> StockResponse.from(outputValues.getStockList()));
}
And create a StockControllerTest
#RunWith(SpringRunner.class)
#WebMvcTest(value = StockController.class, secure = false)
public class StockControllerTest {
#MockBean
private GetAllStocksUseCase getAllStocksUseCase;
#SpyBean
private UseCaseExecutorImpl useCaseExecutor;
#Autowired
private MockMvc mockMvc;
#Configuration
#ComponentScan(basePackages = {"com.example.presenter.rest.api.stock"})
static class Config {
}
#Test
public void deliveryOrderReturnsOk() throws Exception {
Stock stock = TestEntityGenerator.randomStock();
GetAllStocksUseCase.InputValues input = GetAllStocksInputMapper.map(
stock.getMaterialNumber(),
stock.getStorageLocation(),
stock.getPlant());
GetAllStocksUseCase.OutputValues output = new GetAllStocksUseCase.OutputValues(Collections.singletonList(stock));
doReturn(output)
.when(getAllStocksUseCase)
.execute(input);
final String request =
"/api/stocks?materialNumber=" +
stock.getMaterialNumber() + "&plant=" + stock.getPlant() + "&storageLocation=" + stock.getStorageLocation();
RequestBuilder payload = asyncGetRequest(request);
mockMvc.perform(payload)
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.[0].materialNumber", is(stock.getMaterialNumber())))
.andExpect(jsonPath("$.[0].plant", is(stock.getPlant())))
.andExpect(jsonPath("$.[0].storageLocation", is(stock.getStorageLocation())))
.andExpect(jsonPath("$.[0].availableQuantity", is(stock.getAvailableQuantity())))
.andExpect(jsonPath("$.[0].quantity", is(stock.getQuantity())));
}
protected RequestBuilder asyncGetRequest(String url) throws Exception {
return asyncDispatch(mockMvc.perform(get(url))
.andExpect(request().asyncStarted())
.andReturn());
}
}
And have a UseCaseExecutor to run a useCase with some input to generate some output.
GetAllStocksUseCase
#Service
public class GetAllStocksUseCase extends UseCase<GetAllStocksUseCase.InputValues, GetAllStocksUseCase.OutputValues> {
private StockDAO stockDAO;
#Autowired
public GetAllStocksUseCase(StockDAO stockDAO) {
this.stockDAO = stockDAO;
}
#Override
public OutputValues execute(InputValues input) {
return new OutputValues(stockDAO.getAll(input.getStock()));
}
public static class InputValues implements UseCase.InputValues {
private Stock stock;
public InputValues(Stock stock) {
this.stock = stock;
}
public Stock getStock() {
return stock;
}
}
public static class OutputValues implements UseCase.OutputValues {
List<Stock> stockList;
public OutputValues(List<Stock> stockList) {
this.stockList = stockList;
}
public List<Stock> getStockList() {
return stockList;
}
}
}
UseCaseExecutor
#Service
public class UseCaseExecutorImpl implements UseCaseExecutor {
#Override
public <RX, I extends UseCase.InputValues, O extends UseCase.OutputValues> CompletableFuture<RX> execute(
UseCase<I, O> useCase, I input, Function<O, RX> outputMapper) {
return CompletableFuture
.supplyAsync(() -> input)
.thenApplyAsync(useCase::execute)
.thenApplyAsync(outputMapper);
}
}
When I run the test it gives a NullPointException on OutputValues
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.doGet(FrameworkServlet.java:897)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
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:107)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:182)
at com.example.presenter.rest.api.stock.StockControllerTest.deliveryOrderReturnsOk(StockControllerTest.java:61)
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.presenter.rest.api.stock.StockController.lambda$getAllStocks$0(StockController.java:37)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
at java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:443)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Can anyone help me with this problem? It seems that it does not run the execute of useCase before the outputMapper so the OutputValues are null
I am new to unit test in spring Boot. I am trying to run a simple test of the controller.
But i'am getting a NullPointerException.
here is my code :
The controller class:
#RequestMapping("/trainings")
public class TrainingController {
#Autowired
TrainingService ts;
#PostMapping()
public JsonResponse<AllTrainings> getTrainings(){
JsonResponse<AllTrainings> json = new JsonResponse<AllTrainings>();
json.setStatus(JsonResponse.Status.OK);
json.setData(new AllTrainings(ts.getTrainings()));
return json;
}}
The TrainingTest :
#RunWith(SpringRunner.class)
public abstract class TrainingTest {
protected MockMvc mvc;
protected ObjectMapper mapper = new ObjectMapper();
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public abstract void testGetTrainings() throws Exception;
#Test
public abstract void testGetTrainingById() throws Exception;
protected String toJson(Object object) throws JsonProcessingException {
return mapper.writeValueAsString(object);
}
}
The TrainingControllerTest :
public class TrainingControllerTest extends TrainingTest{
#InjectMocks protected TrainingController controller;
#MockBean
TrainingRepository trainingRepo;
#Before
public void setup(){
super.setup();
mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
}
#Override
public void testGetTrainings() throws Exception {
Training ang = new Training("TR0004");
Mockito
.when(this.trainingRepo.findAll())
.thenReturn(Arrays.asList(ang));
mvc.perform(MockMvcRequestBuilders.get("/trainings")
.contentType(MediaType.APPLICATION_JSON_VALUE))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk());
}
And here the error i'am getting:
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.test.web.servlet.MockMvc.perform(MockMvc.java:182)
at fr.ter.forco.training.TrainingControllerTest.testGetTrainings(TrainingControllerTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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.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: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.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.NullPointerException
at fr.ter.forco.controllers.TrainingController.getTrainings(TrainingController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
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:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
... 41 more
The exception appears in the mvc.perform!
I really don't know why i'am getting this error.
Thank you.
I'm not sure why you're getting this error but maybe if you add the #AutoConfigureMockMvc above your test class it could work? I always add this annotation when making use of MockMvc.
I'm trying to test a method in service class which uses ModelMapper to convert entity to dto, but I'm getting NullPointerException at this line mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); in the service class.
Exception
java.lang.NullPointerException
at pro.budthapa.service.impl.StockCategoryServiceImpl.getStockCategoryByIdAndBusinessGroupId(StockCategoryServiceImpl.java:56)
at pro.budthapa.service.impl.StockCategoryServiceImplTest.WhenCategoryPresent_ShouldReturnCategory(StockCategoryServiceImplTest.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
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.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Test Class
#RunWith(MockitoJUnitRunner.class)
public class StockCategoryServiceImplTest {
#Mock
private ModelMapper mapper;
#Mock
private StockCategoryRepository stockCategoryRepository;
#InjectMocks
private StockCategoryServiceImpl stockCategoryService;
#Before
public void setup() {
mapper = new ModelMapper();
}
#Test
public void WhenCategoryPresent_ShouldReturnCategory() throws Exception {
int bgId = 10;
int categoryId = 5;
StockCategory sc = new StockCategory();
sc.setCategoryId(categoryId);
sc.setBusinessGroupId(String.valueOf(bgId));
sc.setDescription("Test Item");
Mockito.when(stockCategoryRepository.findByCategoryIdAndBusinessGroupId(categoryId, String.valueOf(bgId))).thenReturn(Optional.of(sc));
StockCategoryDto result = stockCategoryService.getStockCategoryByIdAndBusinessGroupId(categoryId, bgId);
assertEquals(5, result.getCategoryId() );
assertEquals(10, result.getBusinessGroupId());
assertNotNull(result.getDescription());
Mockito.verify(stockCategoryRepository, Mockito.times(1)).findByCategoryIdAndBusinessGroupId(categoryId, String.valueOf(bgId));
}
}
Service Class
#Service
public class StockCategoryServiceImpl implements StockCategoryService {
private ModelMapper mapper;
private StockCategoryRepository stockCategoryRepository;
public StockCategoryServiceImpl(ModelMapper mapper, StockCategoryRepository stockCategoryRepository) {
this.mapper = mapper;
this.stockCategoryRepository = stockCategoryRepository;
}
#Override
public StockCategoryDto getStockCategoryByIdAndBusinessGroupId(int categoryId, int bgId) {
Optional<StockCategory> cat = stockCategoryRepository.findByCategoryIdAndBusinessGroupId(categoryId, String.valueOf(bgId));
if(cat.isPresent()) {
//getting NullPointerException at this line
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
return mapper.map(cat.get(), StockCategoryDto.class);
}
StockCategoryDto dto = new StockCategoryDto();
dto.setMessage("Category not found for given id: "+categoryId);
return dto;
}
}
You shouldn't reassign your mocked ModelMapper in setup method. Remove this method
And I can't find in your code mock definition for mapper.getConfiguration()
when(mapper.getConfiguration()).thenReturn(...)
You should tell it to mockito.