仍是上次數據不能爲空的問題,寫到了C
層測試。java
先寫一行測試代碼,先期待一個200
,可是咱們是知道的,由於沒有學科類別,這確定會拋出異常,咱們就是想看看Spring
捕獲這個異常以後給出的反饋是什麼狀態碼。web
@Test public void saveTest() throws Exception { logger.debug("基礎測試數據準備"); MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory(); String json = JSON.toJSONString(measurementUnitCategory); this.mockMvc.perform(post(baseUrl) .header(xAuthKey, xAuthToken) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(json)) .andExpect(status().isOk()); }
測試一下,果真,控制檯報錯。spring
可是看一下報錯信息,發現並非咱們期待的一個錯誤的狀態碼,而是200
。同時下面還有異常拋出。json
這說明Spring
爲咱們拋出了這個DataIntegrityViolationException
異常,可是卻沒有幫咱們處理,這就須要咱們手動處理而後返回給前臺狀態碼。app
MockHttpServletResponse: Status = 200 Error message = null Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Application-Context=[application:-1], Content-Type=[application/json;charset=UTF-8], x-auth-token=[1b2b8d9f-3457-4277-879e-2ada48e3599e]} Content type = application/json;charset=UTF-8 Body = {"id":8,"name":"","username":"usersdfdfwef23dfvdfwewef","mobile":"","pinyin":null,"createTime":1528338758059,"updateTime":1528338758059,"status":0,"department":{"id":1,"name":"內蒙古自治區管理部門","code":"","postalCode":"","address":"","legalName":"","legalPhone":"","registrantName":"","registrantPhone":"","registrantTel":null,"registrantMail":"","phone":"","pinyin":"neimengguzishiquguanglibumeng","registerDate":null,"createTime":1528338752423,"updateTime":1528338752423,"status":null,"createUser":null,"departmentType":{"id":1,"name":"管理部門","pinyin":"guanlibumen","createTime":1528338751963,"updateTime":1528338751963,"createUser":null},"district":{"id":1,"districtType":{"id":1,"name":"省","pinyin":"sheng"},"name":"內蒙古自治區","createUser":null,"pinyin":"neimengguzizhiqu","createTime":null,"updateTime":null},"checkAbility":false,"outOfRange":null,"standard":false},"roles":[],"createUser":null,"updateUser":null} Forwarded URL = null Redirected URL = null Cookies = [] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "DISCIPLINE_ID"; SQL statement: insert into measurement_unit_category (id, discipline_id, is_asc) values (null, ?, ?) [23502-194]
理論上咱們全部的異常都是由M
層拋出,直接捕獲或全局異常處理,是不會將異常拋給控制器的。post
因此,咱們須要全局異常處理,M
層拋出異常,直接處理,返回xx
狀態碼,而不將異常拋給控制器。單元測試
@RestController // 以rest形式返回異常信息 @ControllerAdvice // 全局異常處理器 public class GlobalExceptionHandler { private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class.getName()); /** * 手動捕獲數據衝突異常,經測試,該異常系由Spring拋出,但未捕獲 * @return HttpStatus.CONFLICT * 衝突錯誤,409 * 參考: * https://stackoverflow.com/questions/37248719/couldnt-catch-dataintegrityviolationexception-with-spring-data-rest */ @ExceptionHandler(value = DataIntegrityViolationException.class) public ResponseEntity<JsonErrorResult> dataIntegrityViolationException(HttpServletRequest httpServletRequest, Exception exception) { logger.error("---數據不合法:---Host {} invokes url {} ERROR: {}", httpServletRequest.getRemoteHost(), httpServletRequest.getRequestURL(), exception.getMessage()); return new ResponseEntity<>(new JsonErrorResult(httpServletRequest, exception), HttpStatus.CONFLICT); } }
我這裏對狀態碼也不是很熟悉,去StackOverflow
上看到一個老哥是和我遇到了同樣的問題,他解決的方案是捕獲異常返回409
(衝突),參考原文。測試
異常捕獲後,修改測試,期待狀態碼爲409
,Conflict
。this
@Test public void saveTest() throws Exception { logger.debug("基礎測試數據準備"); MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory(); String json = JSON.toJSONString(measurementUnitCategory); logger.debug("無學科的計量單位類別保存,期待409,衝突狀態碼"); this.mockMvc.perform(post(baseUrl) .header(xAuthKey, xAuthToken) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(json)) .andExpect(status().isConflict()); }
從新運行單元測試,經過。url