I have a problem with my Unit Tests for a spring Rest application. In my Unit Tests I always get the problem that I get 401 "Unauthorized" as responsestatus and I don't know how to solve this problem.
My Security config is this:
#Configuration
#EnableWebSecurity
#Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ApiKeyRepository apiKeyRepository;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
ApiKeyAuthFilter filter = new ApiKeyAuthFilter(Globals.HEADER_APIKEY);
filter.setAuthenticationManager(authentication -> {
String principal = (String) authentication.getPrincipal();
Optional<ApiKey> apiKey = apiKeyRepository.findByApiKey(principal);
if (!apiKey.isPresent()) {
throw new BadCredentialsException("The API key was not found or not the expected value.");
}
authentication.setAuthenticated(true);
return authentication;
});
httpSecurity.
csrf().disable().
addFilter(filter).authorizeRequests().anyRequest().authenticated().and().
regexMatcher("(?i)/api/v1/(?:print|resource)(?:/|$).*").
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
My Unit Test looks like:
#RunWith(SpringRunner.class)
#WebMvcTest(ResourceController.class)
public class ResourceControllerTestGetByLogicalFileNameOrDate {
#Autowired
private MockMvc mvc;
#Autowired
private ResourceRepository resourceRepositoryMock;
private Resource setNewResource(long fileSize, String hash, String logicalFileName) {
return getResource(fileSize, hash, logicalFileName);
}
#Test
public void testGetResourceByLogicalFileNameOrDateWithNoInput() throws Exception {
mvc.perform(get(String.format("/api/v1/resource/find/%s", ""))
.header(Globals.HEADER_APIKEY, "lEcsQI09MjUTCMQ5IVvSjf4Anxt+c4nhZAMnU1yDmVI=")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest());
}
I always get the problem that my tests failed. As response I get:
2018-05-07 09:26:52.003 INFO 18692 --- [ main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring FrameworkServlet ''
2018-05-07 09:26:52.003 INFO 18692 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization started
2018-05-07 09:26:52.005 INFO 18692 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization completed in 2 ms
java.lang.AssertionError: Status
Expected :400
Actual :401
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:617)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at at.techsoft.iprint.nano.services.resource.ResourceControllerTestGetByLogicalFileNameOrDate.testGetResourceByLogicalFileNameOrDateWithNoInput(ResourceControllerTestGetByLogicalFileNameOrDate.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
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.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)
Can i turn off the security for the tests? Please can anyone help me to solve this.
When I use the Annotation #ActiveProfiles(value = "test") I get the Exception:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/v1/resource/find
Parameters = {logicalFileName=[Res]}
Headers = {Content-Type=[application/json], X-NANO-APIKEY=[]}
Body = <no character encoding set>
Session Attrs = {SPRING_SECURITY_SAVED_REQUEST=DefaultSavedRequest[http://localhost/api/v1/resource/find?logicalFileName=Res]}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 401
Error message = Unauthorized
Headers = {WWW-Authenticate=[Basic realm="Realm"], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status
Expected :200
Actual :401
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:617)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at at.techsoft.iprint.nano.services.resource.ResourceControllerTestGetByLogicalFileNameOrDate.testGetResourceByLogicalFileNameOrDateWithCorrectLogicalFileName(ResourceControllerTestGetByLogicalFileNameOrDate.java:88)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
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.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)
Since I use Spring Boot 1, I solved it this way:
#WebMvcTest(value = ResourceController.class, secure = false)
Please note that for the newer version of Spring Boot 2 the secure option is not available anymore, so use this:
#WebMvcTest(value = ResourceController.class, excludeAutoConfiguration = {SecurityAutoConfiguration.class})
Looks like your security is the one causes issue. You can use Spring Profile( like #Profile("Production")) as follows:
#Configuration
#EnableWebSecurity
#Profile("Production")
#Order(1)
public class ApiSecurityConfig{
...
}
#RunWith(SpringRunner.class)
#WebMvcTest(ResourceController.class)
#ActiveProfile("test")
public class ResourceControllerTestGetByLogicalFileNameOrDate {
...
}
Reference : https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
Since in local tests you wouldn't want that to be configured, you can use #ActiveProfiles("test") while running the tests. this way, the configurations won't be loaded for local tests.
Related
```java
#RunWith(SpringRunner.class)
#SpringBootTest(classes = DemoApplication.class)
#AutoConfigureMockMvc
#TestPropertySource(locations = "classpath:application-integrationtest.properties")
#EnableAutoConfiguration(exclude = {WebMvcAutoConfiguration.class})
public class DemoControllerTest {
#Autowired
private MockMvc mvc;
#Autowired
private WebApplicationContext context;
#Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(context).dispatchOptions(true).build();
}
#Test
public void getApplicationVersionTest() throws Exception {
mvc.perform(get("/demo/version").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
I have upgraded my springboot version from v2.1.7 to v2.2.5 and since then my controller tests are failing because the mock is returning 404 for all. I have excluded WebMvcAutoConfiguration class for bean instantiation error. Now the mock returns 404 for all.
Error Trace:
java.lang.AssertionError: Status expected:<200> but was:<404>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
at org.springframework.test.web.servlet.result.StatusResultMatchers$$Lambda$879.0000000014CC94F0.match(Unknown Source)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
at com.demo.controller.ControllerTest.getApplicationVersionTest(ControllerTest.java:67)
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.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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:40)
at org.junit.vintage.engine.VintageTestEngine$$Lambda$249.0000000011B25800.accept(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:496)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:486)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:241)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:71)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher$$Lambda$209.0000000011A9CB80.accept(Unknown Source)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.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:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
```
I have upgraded my Spring Boot version from v2.1.7 to v2.2.5 and since then my controller tests are failing because the mock is returning 404 for all. I have excluded `WebMvcAutoConfiguration` class for bean instantiation error. Now the mock returns 404 for all.
Below is the my controller class:
#PropertySource(ignoreResourceNotFound = true, value = "classpath:app-version.properties")
#RestController
#RequestMapping("/demo")
public class DemoController extends CommonController {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoController.class);
private DemoService demoService;
#Value("${environment.name:unknown}")
private String environmentName;
#Value("${buildNumber:unknown}")
private String buildNumber;
private EovService eovService;
#Autowired
public DemoController(DemoService demoService, EovService eovService) {
this.demoService = demoService;
this.eovSqsService = eovSqsService;
}
#GetMapping(value = "/version", produces = {"application/json"}, consumes = {
"application/json"})
public ResponseEntity getApplicationVersionNumber() {
String result = environmentName + " " + buildNumber;
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
Below is what I receive in my console for mockServletResponse. The controller class is starting as expected but the mockMvc is receiving 404 response for all the requests.
12:09:52.247 [] [scheduling-1] INFO
c.t.r.c.h.HeartbeatBatchScheduler - [HEALTH_CHECK][RTCA][svc-demo-status][LOCAL][UP]
12:09:52.254 [] [main] INFO
c.t.r.c.n.c.DemoControllerTest - Started DemoControllerTest in 12.598 seconds (JVM running for 14.864)
12:09:52.398 [] [main] DEBUG
c.t.r.s.j.s.AbstractJWTCommonFilter - In DoFilter JWT Authentication class
MockHttpServletRequest:
HTTP Method = GET
Request URI = /demo/version
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = null
Session Attrs = {}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
12:09:52.468 [] [SpringContextShutdownHook] DEBUG
o.a.h.i.c.PoolingHttpClientConnectionManager - Connection manager is shutting down
12:09:52.469 [] [SpringContextShutdownHook] DEBUG
o.a.h.i.c.PoolingHttpClientConnectionManager - Connection manager shut down
I have started implementing Swagger with version 2.9.2 recently. It worked well without Jackson in other project but as I added same code with Jackson dependency my integration tests were started failing due to not able to covert it(XML string) into Json object.
Tried with different versions of Jackson data format and swagger.
My DTO class:
#Data
#AllArgsConstructor
#NoArgsConstructor
#Wither
public class PartsInfoDTO {
// TODO: 08/10/18 This class should be removed after lexcom start giving remark_line instead of RemarkLine for ex.
#JsonProperty("illustration")
private String Illustration;
#JsonProperty("quantity")
private String Quantity;
#JsonProperty("price")
private Price Price;
#JsonProperty("remark_line")
private String remarkLine;
#JsonProperty("part_number")
#ApiModelProperty(name = "part_number")
private String partNumber;
#JsonProperty("denomination_line")
private String[] denominationLine;
public PartsInfoDTO(PartsInfo partsInfo) {
setDenominationLine(partsInfo.getDenominationLine());
setIllustration(partsInfo.getIllustration());
setPartNumber(partsInfo.getPartNumber());
setPrice(partsInfo.getPrice());
setQuantity(partsInfo.getQuantity());
setRemarkLine(partsInfo.getRemarkLine());
}
}
My Swagger config:
#Configuration
#EnableSwagger2
public class PartsSwaggerConfiguration extends WebMvcConfigurationSupport {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.package.example"))
.paths(regex(PART_INFO_API))
.build();
}
}
Error with stacktrace:
com.fasterxml.jackson.core.JsonParseException: Unexpected character
('<' (code 60)): expected a valid value (number, String, array,
object, 'true', 'false' or 'null') at [Source:
(String)"1121-123453
1INR2ASWS03G102354Drucr";
line: 1, column: 2]
at
com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
at
com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:669)
at
com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:567)
at
com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1894)
at
com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:749)
at
com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4141)
at
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4000)
at
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at
com.vwits.asid.etka.PartInfoControllerTest.getPartInfo(PartInfoControllerTest.java:347)
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.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
com.github.tomakehurst.wiremock.junit.WireMockClassRule$1.evaluate(WireMockClassRule.java:60)
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 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
com.github.tomakehurst.wiremock.junit.WireMockClassRule$1.evaluate(WireMockClassRule.java:70)
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 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)
I'm relatively new to Testing in Mockito, and I'm trying to write few test cases for Controller level testing and I'm getting Null pointer Exception when I'm running the test case. I'm Injecting mocks at controller layer and mocking the service layer methods. Please let me know, the issue
Controller Class:
#RestController
#RequestMapping(value="v1.0/authentication")
public class OauthTokenController {
//Logging
private static final Logger LOG = LoggerFactory.getLogger(OauthTokenController.class);
#Autowired
private SsasServiceImpl ssasService;
#RequestMapping(value="/oauth/token", method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public TokenActivationResponse grantToken(#RequestParam("username") String username, #RequestParam("password") String password, #RequestParam("grant_type") String grant_type){
TokenActivationResponse tokenActivationResponse = new TokenActivationResponse();
SecureString passwordSecured = new SecureString(password);
try{
tokenActivationResponse = ssasService.grantToken(username, passwordSecured, grant_type);
if(tokenActivationResponse == null){
throw new Exception();
}
LOG.info("Printing the response " + tokenActivationResponse);
}catch(Exception e){
LOG.error("Exception in oauth token granting controller", e);
}
return tokenActivationResponse;
}
}
SSASServiceImpl:
public class SSASServiceImpl{
public TokenActivationResponse grantToken(String username, SecureString password, String grant_type) throws IdvException {
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add(USERNAME, username);
body.add(PASSWORD, (password != null) ? String.valueOf(password.getContent()) : null);
body.add(GRANT_TYPE, grant_type);
com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse tokenResponse = new com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse();
TokenActivationResponse response = new TokenActivationResponse();
tokenResponse = restProxy.sendAndReceiveToRestService(body, TOKEN, HttpMethod.POST, com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse.class);
response = transformGrantTokenResp(tokenResponse);
return response;
}
public TokenActivationResponse transformGrantTokenResp(com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse response) throws IdvException {
if (response != null) {
TokenActivationResponse resp = new TokenActivationResponse();
resp.getData().getAttributes().setAccess_token(response.getAccess_token());
resp.getData().getAttributes().setToken_type(response.getToken_type());
resp.getData().getAttributes().setExpires_in(response.getExpires_in());
resp.getData().getAttributes().setScope(response.getScope());
return resp;
} else {
IdvError error = new IdvError();
error.setTitle("Token Error");
throw new IdvException(error);
}
}
}
Test Class:
#RunWith(MockitoJUnitRunner.class)
public class OauthTokenControllerTest {
String accessToken = "d6234595-812d-40fc-b519-2e3456543";
Long expiresIn = 2905L;
String userName = "abcd";
String password = "efghijk";
String grant_type = "password";
String tokenType = "bearer";
String scope = "read write";
#Mock
SsasServiceImpl ssasService = new SsasServiceImpl();
#InjectMocks
OauthTokenController controller = new OauthTokenController();
#Before
public void setUp(){
}
TokenActivationResponse resp = new TokenActivationResponse();
#Test
public void testGrantToken() throws IdvException {
resp.getData().getAttributes().setAccess_token(accessToken);
resp.getData().getAttributes().setToken_type(tokenType);
resp.getData().getAttributes().setExpires_in(expiresIn);
resp.getData().getAttributes().setScope(scope);
SecureString sec = new SecureString(password);
Mockito.when(ssasService.grantToken(any(String.class),any(SecureString.class),any(String.class) )).thenReturn(resp);
final TokenActivationResponse response = controller.grantToken(any(String.class),any(String.class),any(String.class));
assertNotNull(response);
}
}
Exception:
Connected to the target VM, address: '127.0.0.1:60951', transport: 'socket'
16:21:38.387 [main] ERROR com.idv.gateway.controller.OauthTokenController - Exception in oauth token granting controller
java.lang.Exception: null
at com.idv.gateway.controller.OauthTokenController.grantToken(OauthTokenController.java:33)
at com.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.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.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.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)
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.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.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.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.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)
Disconnected from the target VM, address: '127.0.0.1:60951', transport: 'socket'
[MockitoHint] OauthTokenControllerTest.testGrantToken (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.java:60)
[MockitoHint] ...args ok? -> at com.idv.gateway.controller.OauthTokenController.grantToken(OauthTokenController.java:31)
Process finished with exit code -1
I've resolved the issue:
Solution and Fix:
In my TestCase Code, I've replaced the below any(String.class):
Mockito.when(ssasService.grantToken(any(String.class),any(SecureString.class),any(String.class) )).thenReturn(resp);
final TokenActivationResponse response = controller.grantToken(any(String.class),any(String.class),any(String.class));
With (anyString()):
Mockito.when(ssasService.grantToken(anyString(),any(SecureString.class),anyString() )).thenReturn(resp);
final TokenActivationResponse response = controller.grantToken(anyString(),any(String.class),anyString());
One of these Links hepled: Mockito - Invalid use of argument matchers
Also, if you use argument matcher in mockito for one argument, make sure to use for all.
I have a service that returns a zip file. It works fine in dev/prod, a simple a GET /content/{id}/zip will download the file in my browser.
#GetMapping(value = "/content/{id}/zip")
public ResponseEntity<byte[]> getContentZip(#PathVariable String id) {
byte[] zip = ...
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/zip"));
ResponseEntity<byte[]> response = new ResponseEntity<>(zip, headers, HttpStatus.OK);
return response;
}
The problem is with the test:
...
MvcResult result = restStudyMockMvc.perform(get("/content/{id}/zip", content.getId()))
.andExpect(status().isOk())
.andExpect(content().contentType("application/zip")).andReturn();
byte[] bytes = result.getResponse().getContentAsByteArray();
assertThat(bytes).isNotEmpty();
...
It works fine with spring boot 1.5.
Since I've upgraded to spring boot 2. It gives me a "Could not find acceptable representation" exception:
11:04:21.244 [main] DEBUG i.o.v.web.ExceptionControllerAdvice - org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:287)
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:218)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
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:166)
at io.osimis.vsol.web.StudyTest.getStudyZip(StudyTest.java:376)
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.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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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)
Thanks for your help :)
Maybe this is a little late, but I just had the same error and I found this question while searching for the solution.
In my case the error was that I had manually registered a HttpMessageConverter in my test.
this.mockMvc = MockMvcBuilders
...
.setMessageConverters(myJsonHttpMessageConverter)
.build();
By debugging I found out that the internal logic of Spring Mvc is:
If there is a converter configured, use only this converter.
If there is none configured, add all default converters.
Here is the relevant code from org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport:
protected final List<HttpMessageConverter<?>> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList<>();
configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(this.messageConverters);
}
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
So to solve this you could either remove your custom converter so all default converters are used or - if you need it like I did - add the ByteArrayHttpMessageConverter in your test setup.
this.mockMvc = MockMvcBuilders
...
.setMessageConverters(myJsonHttpMessageConverter, new ByteArrayHttpMessageConverter())
.build();
I cannot pass test notFoundFoo since I get NestedServletException excpetion instead of expected FooNotFoundException exception.
What I do wrong in my test?
Controller:
#RestController
#RequestMapping("/api/foo")
public class FooController {
#Autowired
private FooService fooService;
#GetMapping("/{fooId}/status")
#ResponseStatus(HttpStatus.OK)
public PaymentStatus retrievePaymentStatus(#PathVariable String fooId) {
PaymentStatus paymentStatus = fooService.retrievePaymentStatus(fooId);
if (paymentStatus == null) {
throw new InvoiceNotFoundException();
}
// Preconditions.checkNotNull(paymentStatus, new FooNotFoundException());
return paymentStatus;
}
}
FooNotFoundException:
#ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Foo not found")
public class FooNotFoundException extends RuntimeException {
public FooNotFoundException() {
}
public FooNotFoundException(String message) {
super(message);
}
}
Tests:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = App.class)
#AutoConfigureMockMvc
public class FooControllerTest {
#Autowired
FooRepository fooRepository;
#Autowired
BloomFilterManager bloomFilterManager;
#Autowired
private MockMvc mockMvc;
private MediaType CONTENT_TYPE = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(),
Charset.forName("utf8"));
#Test
public void foundFooWithPaymentStatus() throws Exception {
Faker faker = new Faker();
Foo.PaymentStatus[] paymentStatuses = Foo.PaymentStatus.values();
Foo foo= fooRepository.save(new Foo(
faker.number().randomNumber(),
faker.lorem().word(),
faker.number().randomDigit(),
new BigDecimal(Math.random()),
paymentStatuses[faker.number().numberBetween(0, paymentStatuses.length)],
faker.date().between(new Date(), DateUtils.addDays(new Date(), 13))
));
bloomFilterManager.getBloomFilter().put(foo.getId());
RequestBuilder requestBuilder = MockMvcRequestBuilders
.get("/api/foo/{fooId}/status", foo.getId())
.accept(CONTENT_TYPE);
MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(status().isOk())
.andExpect(content().contentType(CONTENT_TYPE))
.andReturn();
String expected = "\"" + foo.getPaymentStatus() + "\"";
assertEquals(expected, result.getResponse().getContentAsString());
}
#Test(expected = FooNotFoundException.class)
public void notFoundFoo() throws Exception {
String fooId = "100000000000000";
RequestBuilder requestBuilder = MockMvcRequestBuilders
.get("/api/foo/{fooId}/status", fooId)
.accept(CONTENT_TYPE);
mockMvc.perform(requestBuilder)
.andExpect(status().isNotFound())
.andExpect(content().contentType(CONTENT_TYPE));
}
Output:
java.lang.Exception: Unexpected exception, expected<org.learn.foo.exception.FooNotFoundException> but was<org.springframework.web.util.NestedServletException>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
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.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: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: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException: org.learn.foo.exception.FooNotFoundException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
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:134)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at org.learn.integration.FooControllerTest.notFoundFoo(FooControllerTest.java:100)
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.ExpectException.evaluate(ExpectException.java:19)
... 28 more
Caused by: java.lang.NullPointerException: org.learn.foo.exception.FooNotFoundException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:900)
at org.learn.foo.controller.FooController.retrievePaymentStatus(FooController.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
... 58 more
UPDATED:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/foo/100000000000000/status
Parameters = {}
Headers = {Accept=[application/json;charset=UTF-8]}
Handler:
Type = org.wixanz.omniva.foo.controller.FooController
Method = public org.wixanz.omniva.foo.domain.foo$PaymentStatus org.wixanz.omniva.foo.controller.FooController.retrievePaymentStatus(java.lang.String)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.wixanz.omniva.foo.exception.InvoiceNotFoundException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = Foo not found
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.Exception: Unexpected exception, expected<org.wixanz.omniva.foo.exception.FooNotFoundException> but was<java.lang.AssertionError>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
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.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: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.AssertionError: Content type not set
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:35)
at org.springframework.test.util.AssertionErrors.assertTrue(AssertionErrors.java:65)
at org.springframework.test.web.servlet.result.ContentResultMatchers$1.match(ContentResultMatchers.java:81)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at org.wixanz.omniva.integration.FooControllerTest.notFoundFoo(FooControllerTest.java:87)
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.ExpectException.evaluate(ExpectException.java:19)
... 28 more
NestedServletException wraps only the cause of the exception.
It is not your actual issue.
Its javadoc defines itself as :
Subclass of ServletException that properly handles a root cause in
terms of message and stacktrace, just like
NestedChecked/RuntimeException does.
Exceptions thrown in a rest controller have to be mapped to a http response. If you didn't it, Spring does that for you by throwing NestedServletException/NestedCheckedException according to the exception nature (checked or runtime).
A Java exception is not a http response.
You cannot let it be thrown as you did in a classic java code.
You have to convert it as something compatible with the http norms.
For Rest controllers you should use #ExceptionHandler and #ControllerAdvice.
#ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler(FooNotFoundException.class)
protected ResponseEntity<Object> handleFooNotFound(FooNotFoundException exception, WebRequest request) {
return handleExceptionInternal(exception, "Foo Not Found",
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
}