单元测试 spring 休息控制器错误处理
Unit testing spring rest controller error handling
我有一个 spring 休息控制器,详情如下
@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 的覆盖信息,我的 catch 块仍然没有被测试覆盖
在您的测试中,尝试使用
Mockito.doThrow(new RuntimeException()).when(this.serviceMock).findAllCountries());
如果遇到编译错误,也可以使用
when(this.serviceMock.findAllCountries()).thenThrow(new RuntimeException());
您必须在错误处理方面收到错误消息
MvcResult mvcResult = resultActions.andExpect(status().isForbidden()).andReturn();
String errMsg = mvcResult.getResponse().getErrorMessage();
我有一个 spring 休息控制器,详情如下
@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 的覆盖信息,我的 catch 块仍然没有被测试覆盖
在您的测试中,尝试使用
Mockito.doThrow(new RuntimeException()).when(this.serviceMock).findAllCountries());
如果遇到编译错误,也可以使用
when(this.serviceMock.findAllCountries()).thenThrow(new RuntimeException());
您必须在错误处理方面收到错误消息
MvcResult mvcResult = resultActions.andExpect(status().isForbidden()).andReturn();
String errMsg = mvcResult.getResponse().getErrorMessage();