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
Related
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 am new to Mockito and i am facing a issue due to a property is not loading in from appication.properties file.
Problem statement: I am trying to mock a method which uses a property from the application.properties file. When the control arrives at the line to load property value it shows null and because of this mockito throws java.lang.NullPointerException.
What i am looking for is how to load the property from application.properties file when mocking a method.
Here i am trying to load global variable partsListGlobal .Please help me how to achieve this.?
Here is my below code snippet.
#Service
public class ClimoDiagnosticReportServImpl implements ClimoDiagnosticReportService {
#Value("${PARTS_LIST}")
private String partsListGlobal;
#Override
public boolean getSomeResult() {
String[] partsListLocal = getPartsList();
List<String> partsList = Arrays.asList(partsListGlobal);
if (partsList.contains("PART_X1"))
return true;
else
return false;
}
public String[] getPartsList() {
return partsListGlobal.split(",");// Here is the error occuring due to partsListGlobal is not loading the value from application.properties file.
}
}
#RunWith(MockitoJUnitRunner.class)
public class ClimoDiagnosticReportServImplTest {
#InjectMocks
private ClimoDiagnosticReportServImpl serviceReference1;
#Mock
private ClimoDiagnosticReportServImpl serviceReference12;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void getSomeResultTest() {
boolean result1 = false;
String[] strArray = new String[2];
strArray[0] = "P1";
strArray[1] = "P2";
Mockito.when(serviceReference12.getPartsList()).thenReturn(strArray);
boolean result2 = serviceReference1.getSomeResult();
Assert.assertEquals(result1,result2);
}
}
Error:
java.lang.NullPointerException at
com.test.serviceimpl.ClimoDiagnosticReportServImpl.getPartsList(ClimoDiagnosticReportServImpl.java:68)
at
com.test.serviceimpl.ClimoDiagnosticReportServImpl.getSomeResult(ClimoDiagnosticReportServImpl.java:57)
at
com.test.serviceimpl.ClimoDiagnosticReportServImplTest.getSomeResultTest(ClimoDiagnosticReportServImplTest.java:74)
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.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:459)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Thanks everyone in advance.
You don't have any dependency to mock in the service. Mockito is thus completely unnecessary. What you need to do is to set the private String field, that is populated by Spring in your application using reflection.
Just follow the best practice os using cnstructor injection instead of field injection, and that will make your code testable (that's one of the reasons why it's a best practice):
#Service
public class ClimoDiagnosticReportServImpl implements ClimoDiagnosticReportService {
private String partsListGlobal;
public ClimoDiagnosticReportServImpl(#Value("${PARTS_LIST}") String partsListGlobal) {
this.partsListGlobal = partsListGlobal;
}
// ...
}
Your test now can be reduced to
public class ClimoDiagnosticReportServImplTest {
#Test
public void shouldReturnTrueIfPropertyContainsPartX1() {
ClimoDiagnosticReportServImpl service = new ClimoDiagnosticReportServImpl("a,b,c,PART_X1,d");
assertTrue(service.getSomeResult());
}
#Test
public void shouldReturnFalseIfPropertyDoesNotContainPartX1() {
ClimoDiagnosticReportServImpl service = new ClimoDiagnosticReportServImpl("a,b,c,d");
assertFalse(service.getSomeResult());
}
}
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.
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"));
}
}
I am trying to write an automation framework using Java and selenium. While running Junit tests, Firefox browser starts but it cannot go to my local site. I get a NullPointer Exception. I am new to Java, any help will be greatly appreciated. Thanks
java.lang.NullPointerException
at WordpressFramework.LoginPage.GoTo(LoginPage.java:18)
at WordpressTest.LoginTests.Admin_User_Can_Log_In(LoginTests.java:26)
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.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
public class LoginTests {
#Before
public void Init()
{
Driver_Setup.Initialize();
}
#Test
public void Admin_User_Can_Log_In(){
LoginPage.GoTo();
LoginPage.LoginAs("rizwan").WithPassword("*****").Login();
public class Driver_Setup {
private static WebDriver instance;
public static WebDriver getWebDriver() {
return instance;
}
public static void setWebDriver(WebDriver instance) {
Driver_Setup.instance = instance;
}
public static void Initialize()
{ WebDriver webdriver=new FirefoxDriver();
webdriver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS); }
}
public class LoginPage {
public static void GoTo() {
Driver_Setup.getWebDriver().navigate().to("http://localhost:57464/wp-login.php");
}
public static LoginCommand LoginAs(String username)
{
return new LoginCommand(username);
}
public static class LoginCommand
{
private String username;
private String password;
public LoginCommand(String username)
{
this.username = username;
}
public LoginCommand WithPassword(String password) {
this.password= password;
return this;
}
public void Login() {
WebElement loginInput = Driver_Setup.getWebDriver().findElement(By.id("user_login"));
loginInput.sendKeys(username);
WebElement passwordInput = Driver_Setup.getWebDriver().findElement(By.id("user_pass"));
WebElement loginButton = Driver_Setup.getWebDriver().findElement(By.id("wp-submit"));
loginButton.click();
}
}
Looks like the problem is inside Driver_Setup class - getWebDriver returns null since you have not called setWebDriver() to set the instance value.