在 Spring MVC 中对控制器 类 进行单元测试是一种好习惯吗
Is it a good practice to unit test controller classes in Spring MVC
我曾经像任何其他普通 Java class 一样对我的控制器 classes 进行单元测试。我的意思是不使用 Spring 的 MockMvc。但后来我意识到,这样我将无法确定我是否正确设置了 MVC 配置。所以如果我有这样的控制器:
@Restcontroller
@RequestMapping("/cars")
public class CarController{
private CarService carService;
public CarController (CarService service){this.carService = service};
@GetMapping
public List<Car> getCar(@RequestParam("filter") String filter){
if(filter!=null && !filter.trim().equal("")){
//omitted for brevity
}
}
}
如果我直接对它的getCar
方法进行单元测试,即使测试通过,也不意味着我的控制器没问题。因此,我没有进行单元测试,而是开始实际进行集成测试。像这样:
mockMvc.perform(get("/v1/cars?filter = Honda")).... bla bla bla
最近有一个问题是先单元测试再集成测试rest controller。乍一看,在我看来,集成测试最终会检查控制器的正确行为。但另一方面,仅仅依靠集成测试有多好。
我个人从未发现单元测试控制器有用。在理想情况下,Controller 相对较小,因为它只调用服务对象的一些方法和 returns 个结果。 IMO 单元测试意味着(过度)使用 verify()
方法。 (即控制器是否使用正确的参数调用服务方法。)
例如,在我的例子中,一个编写良好的控制器方法如下所示:
@LoggingInfo
@PostMapping(value = "/someRoute",
produces = "application/json",
consumes = "application/json")
@ApiOperation(value = "Some description", response = SomeDTO.class)
public @ResponseBody
CompletableFuture<ResponseEntity> someControllerMethod(
@Validated(ValidationSequence.class) @RequestBody SomeDTO someDTO) {
return service
.doSomething(someDTO)
.thenApply((String var) -> ResponseEntity.ok(ResponseDTO.builder()
.myField(Collections.singleton(var)).build()));
}
对该方法进行单元测试会在多大程度上为应用程序增加价值?
对我来说,改变游戏规则的是集成测试的使用。在这里证明所有 spring 魔法是否正常工作,例如:
- 由注释触发的验证器
- (不同的)验证者的顺序
- 转换器(即观看 Jackson 的动作)
- 异常处理程序(被注释的异常处理程序实际捕获的抛出的异常)
希望对您有所帮助。
我曾经像任何其他普通 Java class 一样对我的控制器 classes 进行单元测试。我的意思是不使用 Spring 的 MockMvc。但后来我意识到,这样我将无法确定我是否正确设置了 MVC 配置。所以如果我有这样的控制器:
@Restcontroller
@RequestMapping("/cars")
public class CarController{
private CarService carService;
public CarController (CarService service){this.carService = service};
@GetMapping
public List<Car> getCar(@RequestParam("filter") String filter){
if(filter!=null && !filter.trim().equal("")){
//omitted for brevity
}
}
}
如果我直接对它的getCar
方法进行单元测试,即使测试通过,也不意味着我的控制器没问题。因此,我没有进行单元测试,而是开始实际进行集成测试。像这样:
mockMvc.perform(get("/v1/cars?filter = Honda")).... bla bla bla
最近有一个问题是先单元测试再集成测试rest controller。乍一看,在我看来,集成测试最终会检查控制器的正确行为。但另一方面,仅仅依靠集成测试有多好。
我个人从未发现单元测试控制器有用。在理想情况下,Controller 相对较小,因为它只调用服务对象的一些方法和 returns 个结果。 IMO 单元测试意味着(过度)使用 verify()
方法。 (即控制器是否使用正确的参数调用服务方法。)
例如,在我的例子中,一个编写良好的控制器方法如下所示:
@LoggingInfo
@PostMapping(value = "/someRoute",
produces = "application/json",
consumes = "application/json")
@ApiOperation(value = "Some description", response = SomeDTO.class)
public @ResponseBody
CompletableFuture<ResponseEntity> someControllerMethod(
@Validated(ValidationSequence.class) @RequestBody SomeDTO someDTO) {
return service
.doSomething(someDTO)
.thenApply((String var) -> ResponseEntity.ok(ResponseDTO.builder()
.myField(Collections.singleton(var)).build()));
}
对该方法进行单元测试会在多大程度上为应用程序增加价值?
对我来说,改变游戏规则的是集成测试的使用。在这里证明所有 spring 魔法是否正常工作,例如:
- 由注释触发的验证器
- (不同的)验证者的顺序
- 转换器(即观看 Jackson 的动作)
- 异常处理程序(被注释的异常处理程序实际捕获的抛出的异常)
希望对您有所帮助。