Java Spring Boot 1.4-如何使用验证测试控制器
Spring Boot 1.4有许多优秀的特性,包括@DataJpaTest注释,它可以自动唤醒类路径嵌入式数据库以进行测试。据我所知,它不会在同一类的边界内与TestRestTemplate协同工作 以下测试不起作用:Java Spring Boot 1.4-如何使用验证测试控制器,java,spring-mvc,testing,spring-boot,integration-testing,Java,Spring Mvc,Testing,Spring Boot,Integration Testing,Spring Boot 1.4有许多优秀的特性,包括@DataJpaTest注释,它可以自动唤醒类路径嵌入式数据库以进行测试。据我所知,它不会在同一类的边界内与TestRestTemplate协同工作 以下测试不起作用: @RunWith(SpringRunner.class) @SpringBootTest @DataJpaTest public class PersonControllerTest { private Logger log = Logger.getLogger(ge
@RunWith(SpringRunner.class)
@SpringBootTest
@DataJpaTest
public class PersonControllerTest {
private Logger log = Logger.getLogger(getClass());
private Category category;
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private TestEntityManager entityManager;
@Before
public void init() {
log.info("Initializing...");
category = entityManager.persist(new Category("Staff"));
}
@Test
public void personAddTest() throws Exception {
log.info("PersonAdd test starting...");
PersonRequest request = new PersonRequest("Jimmy");
ResponseEntity<String> response = restTemplate.postForEntity("/Person/Add", request, String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
log.info("PersonAdd test passed");
}
然后猜测切换到推荐的基于模拟的切片方法,但由于控制器如下所示,该方法不起作用:
@RequestMapping(value="/Person/Add", method=RequestMethod.POST)
public ResponseEntity personAdd(@Valid @RequestBody PersonRequest personRequest,
Errors errors)
personValidator.validate(personRequest, errors):
if (errors.hasErrors())
return new ResponseEntity(HttpStatus.BAD_REQUEST);
personService.add(personRequest);
return new ResponseEntity(HttpStatus.OK);
}
。。。如文档所示,模拟personService
很容易,但是如何处理在这种情况下不可模拟的错误
对象?据我所知,没有办法模拟它,因为它不是类字段或方法的返回值
因此,我无法使用切片方法或集成方法测试上述代码,因为@DataJpaTest
不应与控制器一起使用
有没有一种方法可以使用Spring Boot 1.4测试功能测试具有这种体系结构的控制器?您对的理解有点模糊。文档中的“当测试只关注JPA组件时可以使用”。如果要测试控制器层,则不希望使用此注释,因为没有任何WebMvc组件加载到应用程序上下文中。相反,您希望使用,并让它使用您正在测试的@Controller
@RunWith(SpringRunner.class)
@WebMvcTest(PersonController.class)
public class PersonControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
PersonValidator personValidator;
@MockBean
PersonService personService;
@Test
public void personAddTest() throws Exception {
String content = "{\"name\": \"Jimmy\"}";
mockMvc.perform(post("/Person/Add").contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8")
.accept(MediaType.APPLICATION_JSON).content(content)).andExpect(status().isOk());
}
@Test
public void personAddInvalidTest() throws Exception {
String content = "{\"noname\": \"Jimmy\"}";
mockMvc.perform(post("/Person/Add").contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8")
.accept(MediaType.APPLICATION_JSON).content(content)).andExpect(status().isBadRequest());
}
}
不确定您是如何连接验证器和服务的,所以假设您是自动连接它们的
@Controller
public class PersonController {
private PersonValidator personValidator;
private PersonService personService;
public PersonController(PersonValidator personValidator, PersonService personService) {
this.personValidator = personValidator;
this.personService = personService;
}
@RequestMapping(value = "/Person/Add", method = RequestMethod.POST)
public ResponseEntity<String> personAdd(@Valid @RequestBody PersonRequest personRequest, Errors errors) {
personValidator.validate(personRequest, errors);
if (errors.hasErrors()) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
personService.add(personRequest);
return new ResponseEntity<String>(HttpStatus.OK);
}
}
你对这个问题的理解有点偏差。文档中的“当测试只关注JPA组件时可以使用”。如果要测试控制器层,则不希望使用此注释,因为没有任何WebMvc组件加载到应用程序上下文中。相反,您希望使用,并让它使用您正在测试的@Controller
@RunWith(SpringRunner.class)
@WebMvcTest(PersonController.class)
public class PersonControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
PersonValidator personValidator;
@MockBean
PersonService personService;
@Test
public void personAddTest() throws Exception {
String content = "{\"name\": \"Jimmy\"}";
mockMvc.perform(post("/Person/Add").contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8")
.accept(MediaType.APPLICATION_JSON).content(content)).andExpect(status().isOk());
}
@Test
public void personAddInvalidTest() throws Exception {
String content = "{\"noname\": \"Jimmy\"}";
mockMvc.perform(post("/Person/Add").contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8")
.accept(MediaType.APPLICATION_JSON).content(content)).andExpect(status().isBadRequest());
}
}
不确定您是如何连接验证器和服务的,所以假设您是自动连接它们的
@Controller
public class PersonController {
private PersonValidator personValidator;
private PersonService personService;
public PersonController(PersonValidator personValidator, PersonService personService) {
this.personValidator = personValidator;
this.personService = personService;
}
@RequestMapping(value = "/Person/Add", method = RequestMethod.POST)
public ResponseEntity<String> personAdd(@Valid @RequestBody PersonRequest personRequest, Errors errors) {
personValidator.validate(personRequest, errors);
if (errors.hasErrors()) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
personService.add(personRequest);
return new ResponseEntity<String>(HttpStatus.OK);
}
}
您可以模拟URL调用,而不是模拟控制器方法。这将负责错误验证。查看这篇文章@11thdimension值得一提的是,在SpringBoot1.4中,注释发生了轻微的变化,您不需要创建MockMvc,相反,它可以自动连接。查看详细信息。@wilddev如果您可以包括您试图使用的测试类,那么我们可以提供一些建议,说明如何使其按预期的方式工作。@Shawnclak,是的,完成了,看一看,您可以模拟URL调用,而不是模拟控制器方法。这将负责错误验证。查看这篇文章@11thdimension值得一提的是,在SpringBoot1.4中,注释发生了轻微的变化,您不需要创建MockMvc,相反,它可以自动连接。查看详细信息。@wilddev如果您可以包括您试图使用的测试类,那么我们可以提供一些建议,说明如何使其按您期望的方式工作。@Shawnclak,是的,完成了,请看一看