单元测试弹簧控制器错误处理

时间:2016-12-01 15:25:02

标签: java spring unit-testing spring-mvc mockmvc

我有一个弹簧支架控制器,详情如下

@RestController
@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
 */
@Autowired
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);
    }
}

我使用Mockito和Mock Mvc进行单元测试,测试成功路径

public class DataControllerTest implements IAbstractController {

private MockMvc mockMvc;

@Mock
private IDataService serviceMock;

@InjectMocks
private DataController dataController;

@Autowired
WebApplicationContext wac;

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

 @Test
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/country.do")).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)));

    Assert.assertNotNull(ra);
    verify(this.serviceMock, times(1)).findAllCountries();
    verifyNoMoreInteractions(this.serviceMock);

}

但是,我正在努力测试返回错误响应的catch块。这有什么最好的做法?有人可以建议吗?

仅供参考,抽象控制器只包含注释

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public interface IAbstractController {

}

所以我正在尝试的测试是

@Test(expected = Exception.class)
public void testFindAllCountriesThrowsException() throws Exception {
    Mockito.doThrow(new RuntimeException()).when(this.serviceMock.findAllCountries());
    this.mockMvc.perform(get("/data/country.do"));
}

虽然这个测试通过,但是根据EclEmma的覆盖率信息,我的捕获块仍未被测试覆盖

2 个答案:

答案 0 :(得分:0)

在测试中,请尝试使用

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

如果遇到编译错误,您也可以使用

when(this.serviceMock.findAllCountries()).thenThrow(new RuntimeException());

答案 1 :(得分:0)

您必须在错误处理方面收到错误消息

MvcResult mvcResult = resultActions.andExpect(status().isForbidden()).andReturn();
String errMsg = mvcResult.getResponse().getErrorMessage();