我正在学习Spring Integration测试并使用org.springframework.boot.test.web.client.TestRestTemplate
。
我的Spring Boot version is 2.0.2
并使用了一些默认配置。
我的测试课程是:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {
@Autowired
TestRestTemplate restTemplate;
String userBaseUrl = "/api/user/";
UserDto userDto;
@Before
public void setUp() {
EnhancedRandom er = EnhancedRandomBuilder.aNewEnhancedRandomBuilder().collectionSizeRange(1, 1).build();
userDto = er.nextObject(UserDto.class);
}
@Test
public void registerUser() throws Exception{
ResponseEntity<ServiceResponse> responseEntity = restTemplate.postForEntity(userBaseUrl+"register_user", userDto, ServiceResponse.class);
assertEquals(responseEntity.getStatusCode(), HttpStatus.OK);
}
}
控制器端点方法是:
@RequestMapping(value="register_user",method = RequestMethod.POST)
public ResponseEntity<ServiceResponse> registerUser(@RequestHeader HttpHeaders headers, @RequestBody UserDto userDto) {
log.info("Register user");
try {
ServiceResponse serviceResponse = new ServiceResponse("Users listed successfully");
serviceResponse.setData(userService.registerUser(userDto));
return new ResponseEntity<ServiceResponse>(serviceResponse,HttpStatus.OK);
} catch (Exception e) {
GeneralUtil.logError(log, "Error Occurred listing users", e);
HttpHeaders httpHeaders = ServiceResponse.generateRuntimeErrors(e);
return new ResponseEntity<>(httpHeaders, HttpStatus.EXPECTATION_FAILED);
}
}
ServiceResponse是:
public class ServiceResponse {
private Boolean success;
private String message;
private Map<String, Object> params;
private List<?> list;
private Object data;
//getters,setters.
}
当我们手动测试时,此API端点运行良好但在运行测试时不起作用。它会出现此错误:
org.springframework.web.client.RestClientException: Error while extracting response for type [class com.eeposit.lattice.util.ServiceResponse] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:991)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:974)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:725)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:466)
at org.springframework.boot.test.web.client.TestRestTemplate.postForEntity(TestRestTemplate.java:502)
at com.eeposit.lattice.controller.UserControllerIntegrationTest.registerUser(UserControllerIntegrationTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java: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.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:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:241)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100)
... 39 more
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1031)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1290)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235)
... 41 more
我试图解决这个问题谷歌搜索,但无法解决问题。
答案 0 :(得分:2)
我解决了这个问题。我在代码中做了一些修改。我补充说:
public HttpHeaders setHeaders(String accesstoken) {
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(acceptableMediaTypes);
headers.set("accesstoken", accesstoken);
return headers;
}
并将测试方法更改为:
@Test
public void registerUser() throws Exception{
super.getLog().info("Register user integration test.");
HttpHeaders headers = setHeaders(null);
HttpEntity<UserDto> entity = new HttpEntity<UserDto>(userDto,headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(userBaseUrl+"register_user", HttpMethod.POST, entity, String.class);
assertEquals(responseEntity.getStatusCode(), HttpStatus.OK);
assertNotNull(responseEntity.getBody());
ServiceResponse serviceResponse = super.gson.fromJson(responseEntity.getBody(), ServiceResponse.class);
Map<String, Object> data = (Map<String, Object>) serviceResponse.getData();
assertTrue(data.containsKey("accesstoken"));
assertTrue(data.containsKey("user"));
}
而不是使用它:
ResponseEntity<ServiceResponse> responseEntity = restTemplate.postForEntity(userBaseUrl+"register_user", userDto, ServiceResponse.class);
答案 1 :(得分:1)
您的问题可能是因为您收到了一些无法解析为ServiceResponse的错误响应。尝试将ResponseEntity类型更改为String而不是ServiceResponse类型。
ResponseEntity<String> responseEntity = restTemplate.postForEntity(userBaseUrl+"register_user", userDto, String.class);
System.out.println("This is the response as a String" + responseEntity.getBody());
我相信你可以通过这种方式看到通话返回的内容。