我對 Spring Boot 和 JUnit 還很陌生,所以我嘗試構建一個帶有驗證約束的 Rest API,如下所示:
物體類:
@Entity
public class CareerLevel {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer careerLevelId;
@NotNull
@NotEmpty
@Size(max = 50)
private String careerLevel;
// Getters and Setters
}
控制器:
@PostMapping
public ResponseEntity<CareerLevel> postCareerLevel(@RequestBody @Valid CareerLevel careerLevel) {
// saving data
CareerLevel body = careerLevelRepository.save(careerLevel);
return ResponseEntity.status(201).body(body);
}
當我在 Insomnia(或任何其他 HTTP 客戶端)上使用無效值(null、太長的字串等)測驗 post 方法時,它回傳錯誤請求(完全符合我的預期)。但是當我運行我的測驗類時,它拋出了一個名為TransactionSystemException的例外
測驗方法:
@Test
void testPostCareerLevelInvalidValues() {
CareerLevel careerLevel = new CareerLevel();
careerLevel.setCareerLevel("tooLongStriiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing");
ResponseEntity<CareerLevel> response1 = controller.postCareerLevel(careerLevel); // throwing TransactionSystemException
assertEquals(400, response1.getStatusCode().value());
}
如何處理該例外并獲取回應資料?
uj5u.com熱心網友回復:
嗨,我在本地嘗試了您的代碼并添加了一個 lombok 注釋來為物體創建一個構建器。
看 @Builder
我建議MockMvc在測驗控制器類時使用。
我還使用mockito來模擬CareerLevelRepository并將其注入CareerLevelController
@ExtendWith(MockitoExtension.class)
class CareerLevelControllerTest {
@Mock
private CareerLevelRepository careerLevelRepository;
@InjectMocks
private CareerLevelController careerLevelController;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(careerLevelController)
.build();
}
private final ObjectMapper objectMapper = new ObjectMapper();
@Test
void testPostCareerLevelInvalidValues() throws Exception {
CareerLevel request = CareerLevel.builder()
.careerLevel("tooLongStriiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing")
.build();
this.mockMvc
.perform(post("/career-levels").contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().is(400));
}
}
它只是使用 MockMvc 來創建請求而不是呼叫方法。ObjectMapper將我們創建的轉換request為已作為正文發送的 Json。
uj5u.com熱心網友回復:
您的測驗從 HTTP 客戶端運行的原因是因為@Valid注釋驗證了所有傳入請求,因此您得到了正確的回應,即如果您使用比 50 更長的字串來表示careerLevel太長的字串,如果傳遞則為null空值等。
同樣在您的 junit 中不起作用,因為您正在創建careerLevel& 設定值的普通物件。這最終將傳遞給careerLevelRepository.save.
您repository正在嘗試將此物件保存到資料庫中并由于輸入無效而引發TransactionSystemException并且主要是因為提交失敗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/477512.html
