Craig Craig - 1 year ago 100
Java Question

Unit testing spring rest controller error handling

I have a spring rest controller as detailed below

@RequestMapping(value = "/data")
public class DataController {

private final IDataService service;
private static final Logger LOG = Logger.getLogger(DataController.class);

* The Constructor.
* @param service
* the service
public DataController(final IDataService service) {
this.service = service;

// Country
* Find all countries.
* @return the response entity< list< country>>
@RequestMapping(value = "/country", produces = Util.APPLICATION_JSON_UTF8_STRING, method = RequestMethod.GET)
public ResponseEntity<List<Country>> findAllCountries() {
List<Country> countries = new ArrayList<>();
try {
countries = this.service.findAllCountries();
return new ResponseEntity<>(countries, null, HttpStatus.OK);
} catch (final Exception e) {
LOG.error(e.getMessage(), e);
return new ResponseEntity<>(countries, null, HttpStatus.INTERNAL_SERVER_ERROR);

I have a unit test using Mockito and Mock Mvc which tests the successful path

public class DataControllerTest implements IAbstractController {

private MockMvc mockMvc;

private IDataService serviceMock;

private DataController dataController;

WebApplicationContext wac;

* Sets the up.
* @throws Exception
* the exception
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.standaloneSetup(this.dataController).build();

public void testFindAllCountries() throws Exception {

final Country first = new CountryBuilder().id(3L).name("USA").regionId(1L).active(true).build();
final Country second = new CountryBuilder().id(66L).name("India").regionId(2L).active(true).build();
final Country third = new CountryBuilder().id(1L).name("United Kingdom").regionId(4L).active(true).build();

when(this.serviceMock.findAllCountries()).thenReturn(Arrays.asList(first, second, third));

final ResultActions ra = this.mockMvc.perform(get("/data/")).andExpect(status().isOk())
.andExpect(content().contentType(Util.APPLICATION_JSON_UTF8)).andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].id", is(3))).andExpect(jsonPath("$[0].name", is("USA")))
.andExpect(jsonPath("$[0].regionId", is(1))).andExpect(jsonPath("$[0].active", is(true)))
.andExpect(jsonPath("$[1].id", is(66))).andExpect(jsonPath("$[1].name", is("India")))
.andExpect(jsonPath("$[1].regionId", is(2))).andExpect(jsonPath("$[1].active", is(true)))
.andExpect(jsonPath("$[2].id", is(1))).andExpect(jsonPath("$[2].name", is("United Kingdom")))
.andExpect(jsonPath("$[2].regionId", is(4))).andExpect(jsonPath("$[2].active", is(true)));

verify(this.serviceMock, times(1)).findAllCountries();


However, I am struggling to test the catch block where an error response is returned. What are the best practices around this? Can anyone advise?

FYI the Abstract controller just contains annotations

public interface IAbstractController {


So the test I am trying is

@Test(expected = Exception.class)
public void testFindAllCountriesThrowsException() throws Exception {
Mockito.doThrow(new RuntimeException()).when(this.serviceMock.findAllCountries());

Whilst this test passes, accorrding to the coverage infor from EclEmma, my catch block is still not being covered by the test

Answer Source

In your test, try using

Mockito.doThrow(new RuntimeException()).when(this.serviceMock).findAllCountries());

If you encounter a compile error, you might also use

when(this.serviceMock.findAllCountries()).thenThrow(new RuntimeException());
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download