I am writing a junit test case to call an api deployed on aws api gateway.
The code is :
#Test
public void testAwsApiUtilsMakeRequest() throws Exception {
RetryPolicy retryPolicy = new RetryPolicy(PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION,
PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY,
3, true);
ClientConfiguration cfg = Mockito.mock(ClientConfiguration.class);
RetryPolicyAdapter rpa = new RetryPolicyAdapter(retryPolicy, cfg);
System.out.println(rpa.getLegacyRetryPolicy());
cfg.setRetryPolicy(rpa.getLegacyRetryPolicy());
cfg.withMaxErrorRetry(3);
Request request = Mockito.mock(Request.class);
request.setHttpMethod(HttpMethodName.GET);
request.setEndpoint(new URI("http://localhost:" + port));
request.setResourcePath("/myapro-1.0.0/profiles/" + "123");
request.addHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON.toString());
Response<AmazonWebServiceResponse<String>> awsResponse = Mockito.mock(Response.class);
Mockito.when(awsApiUtils.postToAwsClient(request, cfg))
.thenReturn(awsResponse);
Mockito.when(awsApiUtils.makeRequest(request))
.thenReturn(awsResponse.getAwsResponse().getResult());
//assertThat(sdReprocessController.getProfileInfo("123"));
}
When I am running the test I am getting the error: java.lang.IllegalArgumentException: legacyRetryPolicy cannot be null
Does anyone know how to resolve the issue / how to set legacyRetryPolicy? Thanks.
Here is the log:
java.lang.IllegalArgumentException: legacyRetryPolicy cannot be null
at com.amazonaws.util.ValidationUtils.assertNotNull(ValidationUtils.java:37)
at com.amazonaws.retry.RetryPolicyAdapter.<init>(RetryPolicyAdapter.java:36)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:347)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:320)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:308)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:286)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:269)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:253)
at org.act.leap.util.AwsApiUtils.postToAwsClient(AwsApiUtils.java:62)
at org.act.leap.resttemplate.controller.SdReprocessControllerTest.testAwsApiUtilsMakeRequest(SdReprocessControllerTest.java:251)
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:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
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.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
I am using Spring Boot REST and Mockito. How can I write a test case?
Error:
java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
at java.util.concurrent.ConcurrentHashMap$KeySetView.add(ConcurrentHashMap.java:4595)
at com.mastercard.customer.data.management.refdata.service.RegionService.lambda$2(RegionService.java:58)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.mastercard.customer.data.management.refdata.service.RegionService.findAllRegions(RegionService.java:49)
at com.mastercard.customer.data.management.refdata.service.RegionServiceTest.findAllRegions_SuccessTest(RegionServiceTest.java:68)
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.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:44)
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.DefaultInternalRunner$1.run(DefaultInternalRunner.java:74)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:80)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
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)
Code
public List<Employee> findAllEmployees() {
List<Object> obj = mongoTemplate.query(Department.class).distinct("employees").all();
List<Employee> employees = null;
if (!CollectionUtils.isEmpty(obj)) {
employees = obj.stream().map(e -> (Employee) e).filter(distinctByKey(Employee::getEmployeeCd)).collect(Collectors.toList());
}
return employees;
}
public <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
Test case
#Test
public void findEmp() {
when(mongoTemplate.query(Department.class)).thenReturn(executableDepartment);
when(mongoTemplate.query(Department.class).distinct("employees")).thenReturn(distinctDepartment);
when(mongoTemplate.query(Department.class).distinct("employees").all()).thenReturn(obj);
when(obj.stream()).thenReturn(Stream.of(obj));
when(obj.stream().map(e -> (Region) e).thenReturn(Stream.of(region));
assertNotNull(empService.findAllRegions());
}
1) Try to set up you mocking one by one instead of cascading the calls:
when(mongoTemplate.query(Department.class)).thenReturn(executableDepartment);
when(executableDepartment).distinct("employees")).thenReturn(distinctDepartment);
when(distinctDepartment.all()).thenReturn(obj);
The executableDepartment and distinctDepartment need to be mocks as well of course.
2) Do not mock the List interface. Feed it with pre-configured data and allow the SUT to work on it as it is. Sp mocking should only be used in this part:
mongoTemplate.query(Department.class).distinct("employees").all();
So the part that provides data. But leave the actual logic to run as it is.
Is there a configuration to allow Jackson gracefully handle members discrepancy between member variable's type and that used in the getter/setter? For example, if a private variable is declared with type Long and its accessor methods are using type long, we have a problem. Also, we are dealing with code which cannot be changed:
For example, consider this class:
public class EventArgs {
private Long id;
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
Consider the corresponding test:
#Test
public void shouldSerializeToString() {
ObjectMapper mapper = new ObjectMapper();
String value = null;
try {
value = mapper.writeValueAsString(new EventArgs());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
Assert.assertNotNull(value);
}
The test fails with this exception:
com.fasterxml.jackson.databind.JsonMappingException: (was
java.lang.NullPointerException) (through reference chain:
com.sailpoint.orchestration.zeebe.model.EventArgs["id"]) at
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
at
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
at
com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:729)
at
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166)
at
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at
com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4094)
at
com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3404)
at
com.sailpoint.orchestration.zeebe.workers.EventArgsTests.shouldSerializeToString(EventArgsTests.java:19)
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.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.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.sailpoint.orchestration.zeebe.model.EventArgs.getId(EventArgs.java:18)
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
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688)
at
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:721)
... 28 more
java.lang.AssertionError at org.junit.Assert.fail(Assert.java:86) at
org.junit.Assert.assertTrue(Assert.java:41) at
org.junit.Assert.assertNotNull(Assert.java:712) at
org.junit.Assert.assertNotNull(Assert.java:722) at
com.sailpoint.orchestration.zeebe.workers.EventArgsTests.shouldSerializeToString(EventArgsTests.java:24)
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.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.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)
You could tell Jackson not to use getters and setters and use fields only :
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); //turn off everything
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); // only use fields
or if you want to disable ONLY getters and setters and use fields (and allow other like JsonCreator) :
mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
The output JSON is then :
{"id":null,"message":null}
That code take me an error, i try with Spring Boot and Mockito, Junit4:
#PostMapping(value = Constants.LOGOUT_URL)
public String logout (HttpServletRequest request) throws ApiException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null) {
try {
String tokenValue = authHeader.replace("Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
tokenStore.removeAccessToken(accessToken);
} catch (Exception e) {
return HttpStatus.NOT_FOUND.toString();
}
}
return Utils.convertDateTime();
}
#Test
public void logout() throws Exception, ApiException {
//String result = "{\"date\":\"20190212:0000\"}";
//Mockito.when(controller.logout(any())).thenReturn(result);
mockMvc.perform(MockMvcRequestBuilders.post(REST_REQUEST_PATH)
.header("principal", "admin")
.header("authorization", "authtoken")
.contentType(MediaType.APPLICATION_JSON)
.accept("application/json"))
.andExpect(status().isOk())
.andDo(document("logout",
responseFields(fieldWithPath("date").description("Fecha de entrega de la respuesta.")
)));
}
This is the Stack Trace error
14:17:29.972 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling
14:17:29.973 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Successfully completed request
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.List
at org.springframework.restdocs.payload.JsonContentHandler.isEmpty(JsonContentHandler.java:147)
at org.springframework.restdocs.payload.JsonContentHandler.getUndocumentedContent(JsonContentHandler.java:119)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:242)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:169)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:83)
at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:206)
at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:55)
at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:183)
at com.sodexo.oneapp.api.auth.AuthControllerTest.logout(AuthControllerTest.java:90)
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.springframework.restdocs.JUnitRestDocumentation$1.evaluate(JUnitRestDocumentation.java:63)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
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)
I'm trying to write some tests using Mockito and I managed to write them for findAll and delete operations but for the create and update, they won't work.
#RunWith(MockitoJUnitRunner.class)
public class RentedControllerTest {
#Mock
private RentedService rentalService;
#Mock
private MovieService movieService;
#Mock
private ClientService clientService;
#InjectMocks
private RentedController rentalController;
#InjectMocks
private MovieController movieController;
#InjectMocks
private ClientController clientController;
#Before
public void setUp() throws Exception {
initMocks(this);
}
#Test
public void getMovies() throws Exception {
List<Movie> movies = new ArrayList<>();
movies.add(mock(Movie.class));
// System.out.println(movies.toString());
when(movieService.findAll()).thenReturn(movies);
//// System.out.println(movieService.findAll().toString());
MoviesDto response = movieController.getMovies();
assertEquals("should be 1 movie", 1, response.getMovies().size());
}
#Test
public void updateMovie() throws Exception {
Movie movie = new Movie(2,"Lotr",0, "dir2", 2003);
MovieDto movieDto = mock(MovieDto.class);
System.out.println(movie.toString());
when(movieService.updateMovie(anyInt(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(movie);
// Movie m = new Movie();
// m = movieService.updateMovie(2,"Lotrrrrr",0, "dir2", 2003);
// System.out.println(m.toString());
Map<String, MovieDto> map = movieController.updateMovie(2, movieDto);
System.out.println(map.toString());
assertEquals("Title should be Lots", "Lotr", map.get("movie").getName());
}
#Test
public void createMovie() throws Exception {
Movie movie = new Movie(2,"Lotr",0, "dir2", 2003);
MovieDto movieDto = mock(MovieDto.class);
when(movieService.createMovie(anyInt(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(movie);
Map<String, MovieDto> map = movieController.createMovie(movieDto);
assertEquals("Title should be Lotr", "Lotr", map.get("movie").getName());
}
#Test
public void deleteMovie() throws Exception {
ResponseEntity response = movieController.deleteMovie(1);
assertEquals("Http status should be OK", HttpStatus.OK, response.getStatusCode());
}
}
So the line "when(movieService.update....) work's just fine. I tested it with the write lines as you can see in the code and it works. The problem is here
Map<String, MovieDto> map = movieController.updateMovie(2, movieDto);
I gives me NullPointerException inside that method. The method looks like this:
#RequestMapping(value = "/movies/{movieId}", method = RequestMethod.PUT, consumes = CatalogMediaType.API_JSON)
public Map<String, MovieDto> updateMovie(#PathVariable final Integer movieId,
#RequestBody final MovieDto movieDto) {
log.trace("updateMovie: movieId={} movieDto={}", movieId, movieDto);
Movie movie = movieService.updateMovie(movieId, movieDto.getMovie().getName(), movieDto.getMovie().getNumberofrentals(), movieDto.getMovie().getDirector(), movieDto.getMovie().getYear());
Map<String, MovieDto> movieDtoMap = new HashMap<>();
movieDtoMap.put("movie", new MovieDto(movie));
log.trace("updateMovie: movieDtoMap={}", movieDtoMap);
return movieDtoMap;
}
The application itself works perfectly, the problem arises only when runing the mockito tests.
java.lang.NullPointerException
at ro.ubb.stcatalog.web.controller.MovieController.updateMovie(MovieController.java:41)
at ro.ubb.stcatalog.web.controller.RentedControllerTest.updateMovie(RentedControllerTest.java:82)
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:483)
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.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.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:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
2016-05-26T23:51:52,845 TRACE [main]: MovieController - createMovie: moviesDto=Mock for MovieDto, hashCode: 825249556
java.lang.NullPointerException
at ro.ubb.stcatalog.web.controller.MovieController.createMovie(MovieController.java:54)
at ro.ubb.stcatalog.web.controller.RentedControllerTest.createMovie(RentedControllerTest.java:92)
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:483)
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.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.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:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
I don't really understand what the problem is if the findAll and delete work just fine... Any ideas?
I believe the mocking of MovieDto class is causing the NPE, as your controller is expecting a few params to be present in the DTO, which are not being set by the mock(), such as movieDto.getMovie().getName().
Create a MovieDto object from scratch with all the required params, or set the params post mocking, and you should be fine.
The following should work.
#Test
public void updateMovie() throws Exception {
Movie movie = new Movie(2,"Lotr",0, "dir2", 2003);
MovieDto movieDto = mock(MovieDto.class);
// Added the following line
movieDto.setMovie(movie);
System.out.println(movie.toString());
when(movieService.updateMovie(anyInt(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(movie);
Map<String, MovieDto> map = movieController.updateMovie(2, movieDto);
System.out.println(map.toString());
assertEquals("Title should be Lots", "Lotr", map.get("movie").getName());
}
Looks like some dependency for the MovieController isn't getting set.
java.lang.NullPointerException
at ro.ubb.stcatalog.web.controller.MovieController.createMovie(MovieController.java:54)
You need to populate movieDto first. When you are doing get in the actual code its like you are doing get on a null which gives a NullPointer. And also Both values should be same. In when condition you are telling movieId as anyInt() and in the actual method call you are giving it as 2. That won't work. Both should be same as below.
when(movieService.updateMovie(**2**, anyString(), anyInt(), anyString(), anyInt())).thenReturn(movie);
Map<String, MovieDto> map = movieController.updateMovie(**2**, movieDto);