Reputation: 11647
According to the Spring Boot documentation:
Note that
TestRestTemplate
is now available as bean whenever@SpringBootTest
is used. It’s pre-configured to resolve relative paths tohttp://localhost:${local.server.port}
. We could have also used the@LocalServerPort
annotation to inject the actual port that the server is running on into a test field.
I have a RESTFul application that returns XML data. The POM file contains jackson-dataformat-xml
In the test class, I have the following code:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class XMLDataTest {
@Autowired
private TestRestTemplate restTemplate;
...
ResponseEntity<List<City>> cities = restTemplate.exchange(appPath,
HttpMethod.GET, null, paramType);
assertThat(cities.getBody()).hasSize(8);
assertThat(cities.getBody()).contains(this.c1, this.c2, this.c3);
If the appPath
equals to the full URL, such as http://localhost:9234/myapp/cities
, then the test runs OK. If appPath
equals to a relative path, /myapp/cities
, I get a JSON exception. It looks like relative paths force JSON conversion.
Exception:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@4628a02b; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:338)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:269)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2938)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:96)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:924)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:908)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:662)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:620)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:566)
at org.springframework.boot.test.web.client.TestRestTemplate.exchange(TestRestTemplate.java:812)
at com.zetcode.test.RestControllerTest.allCitiesTest(RestControllerTest.java:51)
How to fix this?
Upvotes: 0
Views: 2458
Reputation: 691913
The API returns a JSON object, and you expect a JSON array, hence the exception. To make it return XML, you need to specify the Accept header of your request.
Useful trick: when debugging such problems, use String.class as the expected response type, and print the result.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<List<City>> cities = restTemplate.exchange(appPath,
HttpMethod.GET, entity, paramType);
Upvotes: 2