@Pattern注解在junit 4中不起作用

jk9hmnmh  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(302)

我正在开发一个为用户执行CRUD操作的示例springboot应用程序。
我创建了一个用户API。UsersController.java是控制器代码。

    • 用户控制器. java**
@PostMapping(value = "/users", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
    @ApiOperation(value = "API endpoint to save users", notes = "API endpoint to save users")
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = ErrorConstants.OK),
        @ApiResponse(code = 400, message = ErrorConstants.BAD_REQUEST),
        @ApiResponse(code = 403, message = ErrorConstants.FORBIDDEN),
        @ApiResponse(code = 500, message = ErrorConstants.INTERNAL_SERVER_ERROR) }
    )
    public ResponseEntity<?> addUsers(@Valid @RequestBody UserDto userDto) {
        try {
            return new ResponseEntity<>(userService.createUsers(userDto), HttpStatus.OK);
        } catch (BadRequestException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

DTO如下

    • 用户数据到. java**
@JsonInclude(Include.NON_NULL)
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class UserDto {
    
        private String id;
    
        @Size(min = 4, max = 36, message = "Name should be between 4 to 36 characters long.")
        @Pattern(regexp = "^[^&+;=#<>*{}@:]*$", message = "Name field Should not contain special chars")
        private String name;
    
        private String address;
        
        private String mobileNo;
    }

如您所见,我已经向name字段添加了验证,此外,我还创建了一个控制器通知来处理异常。

    • 异常控制器建议. java**
import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    
    @RestControllerAdvice
    public class ExceptionControllerAdvise {
    
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public ResponseEntity<ErrorResponse> validException(MethodArgumentNotValidException exception) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

如果为注解字段引发任何验证异常,则上述类将返回错误。
当我运行应用程序并使用无效名称(包含特殊字符的名称)调用API时,我得到了一个400 bad request异常。
但是当我尝试为无效数据编写junit测试用例时,测试用例通过了。(即@Pattern注解不适用于junit)
下面是我的junit测试样本。

@Test
    public void test0_createUsersWithInvalidName() {
        UserDto dto = new UserDto();
        dto.setName("Apple&sons!")
        dto.setAddress("abc");
        ResponseEntity<?> response = usersController.addUsers(dto)
        assertTrue(response.getStatusCode().equals(HttpStatus.BAD_REQUEST));
    }

上面的测试用例通过了,但是我收到了一个java.lang.AssertionError错误;调试此问题时,我发现收到的状态为200 OK,而不是400 BAD REQUEST
有谁能帮帮我吗?谢谢

rdlzhqv9

rdlzhqv91#

如果您想在控制器中测试您的bean validation规则,您可以通过模拟将在服务类或集成测试中发生的异常(通过模拟错误值)来实现。您还可以改进controller中的代码。这里,您将在catch部分返回一个BAD_REQUEST。这是你的ControllerAdvice类的角色,相反你应该抛出一个BadRequestException请求异常,这个异常将被传输到你的ControllerAdvice

  • 主计长 *
@PostMapping(value = "/users", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
@ApiOperation(value = "API endpoint to save users", notes = "API endpoint to save users")
@ApiResponses(value = {
    @ApiResponse(code = 200, message = ErrorConstants.OK),
    @ApiResponse(code = 400, message = ErrorConstants.BAD_REQUEST),
    @ApiResponse(code = 403, message = ErrorConstants.FORBIDDEN),
    @ApiResponse(code = 500, message = ErrorConstants.INTERNAL_SERVER_ERROR) }
)
public ResponseEntity<?> addUsers(@Valid @RequestBody UserDto userDto) {
    try {
        return new ResponseEntity<>(userService.createUsers(userDto), HttpStatus.OK);
    } catch (MethodArgumentNotValidException e) {
        throw new BadRequestException("YOUR MESSAGE", e); // the e in parameter to get the root cause if you send message from your validation
    } catch (Exception e) {
        throw new InternalServerErrorException("YOUR MESSAGE", e); // the e in parameter to get the root cause
    }
}
  • 控制器建议 *
@RestControllerAdvice
public class ExceptionControllerAdvise {

    @ExceptionHandler(value = BadRequestException.class)
    public ResponseEntity<ErrorResponse> validException(BadRequestException exception) {
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(value = InternalServerErrorException.class)
    public ResponseEntity<ErrorResponse> serverException(InternalServerErrorExceptionexception) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • 测试类别 *
@Test
public void test0_createUsersWithInvalidName() {
   
    ...
    
    when(userService
    .createUsers(userDto))
    .thenThrow(MethodArgumentNotValidException.class);

   ...
   // Here use mockMvc instead
}

测试代码的这一部分将用于集成测试:

UserDto dto = new UserDto();
dto.setName("Apple&sons!")
dto.setAddress("abc");

另外,如何构造ErrorResponse

相关问题