多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## maven依赖 spring-boot-starter-test包含引入了JUnit。 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` ## 注解介绍 * @RunWith(SpringRunner.class):指定JUnit使用Spring环境运行。SpringRunner 继承了SpringJUnit4ClassRunner,没有扩展任何功能,使用前者,名字简短而已。 * @SpringBootTest:会模拟SpringBoot应用启动,寻找带有SpringBootApplication的配置类启动,创建ApplicationContext容器。 * classes:此属性指定Spring Boot工程的启动类 * webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,指定一个随机端口,去启动内置的web应用服务器 * @WebMvcTest:只实例化Controller层,如果Controller层对Service层中有依赖关系,可以使用@MockBean注解进行模拟 * @LocalServerPort:该注解会把springboot内置web应用服务器启动端口赋给其注解的字段。 * @TestConfiguration:用它我们可以在一般的@Configuration之外补充测试专门用的Bean或者自定义的配置。 * @TestComponent:是另一种@Component,在语义上用来指定某个Bean是专门用于测试的。 * @MockBean:模拟Spring环境,解决测试中依赖问题,以下`@WebMvcTest使用`中即是@MockBean的经典使用 ## @SpringBootTest使用 ``` @RunWith(SpringRunner.class) @SpringBootTest(classes = StartUpApplication.class,webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloControllerTest { @LocalServerPort private int port; private String baseUrl; @Autowired private TestRestTemplate restTemplate; @BeforeEach public void setUp(){ this.baseUrl="http://127.0.0.1:"+port; } @Test public void index() { System.out.println("request url is: "+baseUrl); ResponseEntity<String> response = restTemplate.getForEntity(baseUrl, String.class); System.out.println(response.getBody()); Assertions.assertEquals(response.getBody(),"Welcome to Spring Boot!"); } } ``` ## MockMvc详解 * 上面介绍的@SpringBootTest测试适合Service和DAO层方法的测试,不需要创建MockMvc * 对Controller的方法进行测试,需要模拟HTTP环境,如果启动服务器,效率很低,Spring引入了MockMVC,实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用 * 注解:@AutoConfigureMockMvc,相当于new MockMvc * 工具类:MockMvc(3步) * perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理; * MockMvcRequestBuilders提供了get/post/put/delete/upload等http请求的方式 * 提供了header/contentType/cookie/characterEncoding/params等设置request参数的方式 * ResultActions * andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确; * andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台; * andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理; * MvcResult(自定义Assert) * getModelAndView:获得控制层设置的ModeAndView对象 * getResponse:获得最终响应结果 ``` @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class UserControllerTest { @Autowired private MockMvc mockMvc; @Test public void testHello() throws Exception { /* * 1、mockMvc.perform执行一个请求。 * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。 * 3、ResultActions.param添加请求传值 * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型 * 5、ResultActions.andExpect添加执行完成后的断言。 * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情 * 比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。 * 7、ResultActions.andReturn表示执行完成后返回相应的结果,返回MvcResult。 */ MvcResult result = mockMvc.perform(MockMvcRequestBuilders .get("/hello") // 设置返回值类型为utf-8,否则默认为ISO-8859-1 .accept(MediaType.APPLICATION_JSON_UTF8_VALUE) .param("name", "Tom")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("Hello Tom!")) .andDo(MockMvcResultHandlers.print()).andReturn(); Assert.assertNotNull(result.getModelAndView().getModel().get("user")); } } ``` ## @WebMvcTest使用 ``` @RunWith(SpringRunner.class) @WebMvcTest(UserController.class) public class UserControllerTest { @Autowired private MockMvc mockMvc; //模拟出一个userService @MockBean private UserService userService; @Test public void testService() throws Exception { //模拟userService.findByUserId(1)的行为 when(userService.findByUserId(1)).thenReturn(new User(1,"张三")); String result = this.mockMvc.perform(get("/user/1")) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.name").value("张三")) .andReturn().getResponse().getContentAsString(); System.out.println("result : " + result); } } ```