I'm running a Spring Boot app and I've registered a new HttpMessageConverter called CsvCompactVenueHttpMessageConverter, here's the code for it:
@Component
public class CsvCompactVenueHttpMessageConverter extends
AbstractHttpMessageConverter<Collection<CompactVenue>> {
public CsvCompactVenueHttpMessageConverter() {
super(MediaType.valueOf(TEXT_CSV));
}
>> message converter implementation code <<
}
It extends AbstractHttpMessageConverter and is registered as a bean on class WebConfiguration:
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public CsvCompactVenueHttpMessageConverter csvCompactVenueHttpMessageConverter() {
return new CsvCompactVenueHttpMessageConverter();
}
}
Then I have a rest resource called FoursquareResource:
@RestController
@RequestMapping("/foursquare")
public class FoursquareResource {
@Autowired
FoursquareService foursquareService;
@GetMapping(value = "/{location}", produces = {"application/json", "text/csv"})
public Collection<CompactVenue> searchVenuesByLocationAndIncreasingRange(@PathVariable String location, @RequestParam(defaultValue = "1") Integer numQueries) throws FoursquareApiException, FoursquareServiceException {
return foursquareService.searchVenuesByLocationAndIncreasingRange(location, numQueries);
}
}
When I run the app and call http://localhost:8080/foursquare/New York NY it works fine and renders the text/csv response.
But when running the test with RestAssured and @SpringBootTest I get a HTTP 406 response (because I think it did not register correctly the HttpMessageConverter for text/csv), here's the code:
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class FoursquareResourceTest {
@Mock
FoursquareService foursquareService;
@InjectMocks
FoursquareResource foursquareResource;
@Before
public void before() throws Exception {
CompactVenue venue = new CompactVenue();
FieldUtils.writeField(venue, "id", "aUfmEW745", true);
Collection<CompactVenue> venues = new ArrayList<>();
venues.add(venue);
when(foursquareService.searchVenuesByLocationAndIncreasingRange(any(), any())).thenReturn(venues);
}
@Test
public void testSearchVenuesByLocationAndIncreasingRangeCsv() throws Exception {
MockMvcResponse response =
given().
accept("text/csv").
standaloneSetup(foursquareResource).
when().
get(String.format("/foursquare/%s?numQueries=%d",location,numQueries)).
then().
statusCode(200).
extract().response();
log.info(response.body().print());
}
}
I'm not sure why do I get a right answer when running the Spring Boot app but the 406 error when running as a Test. It looks like the new HttpMessageConverter is not registered on the tests but I can't see why.
Thanks and regards.
406 Not Acceptable just means that the controller is not able to serve the representation, requested by the client. In your case the client indicates its capability to read text/csv by sending Accept header, but the controller is not able to send text/csv back. Most probably lacking your converter. To understand why, it is important to understand one thing about MockMvc.
It is not clear, how your MockMvc is initialized, but I assume it is standalone setup. Be aware that standaloneSetup creates a new application context, where the beans from you standard configurations are not registered, including your custom converter. This explains, why the code works in a "normal" run, but fails in test. To overcome this, either use webAppContextSetup (which will start the application and embedded Jetty/Tomcat) with injected application context or manually set the converters by calling setMessageConverters on StandaloneMockMvcBuilder. For example,
mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.setMessageConverters(new SomeConverter(),
new SomeOtherConverter())
.build();
You can then reuse the mockMvc object in your REST Assure just by calling
RestAssuredMockMvc.mockMvc(mockMvc);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With