一、IDEA自动生成测试类
1.安装插件JUnitGenerator V2.0
File---->Settings---->Browse Repositories

2.安装好后把JUnit和JUnitGenerator V2.0一起勾上

3.配置插件
把package上test.前缀去掉

配置测试类生成的地址
${SOURCEPATH}/../../test/java/${PACKAGE}/${FILENAME}

4.对着要生成的类



二、测试service类
@SpringBootTest会加载spring的上下文,这样可以使用@Autowired注入Bean
- package com.sid.service.impl;
-
- import com.sid.service.UserService;
- import org.junit.After;
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringRunner;
- import static org.hamcrest.CoreMatchers.*;
-
- import static org.junit.Assert.*;
-
- /**
- * @Description: Service层单元测试 启动了服务
- * @Param:
- * @return:
- * @Author: Sid
- * @Date: 2018-10-24 13:53
- * @since: 1.0
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class UserServiceImplTest {
-
-
- /**
- * @Description: 直接测试service 用IOC注入进来 这样run的时候会先启动springboot项目
- * @Param:
- * @return:
- * @Author: Sid
- * @Date: 2018-10-24 13:42
- * @since: 1.0
- */
- @Autowired
- UserService userService;
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void set() {
- userService.set("sid:test:string:key:","lalala");
- String value = userService.get("sid:test:string:key:");
- Assert.assertEquals("lalala",value);
- //可以只使用 assertThat 一个断言语句,结合 Hamcrest 提供的匹配符,就可以表达全部的测试思想
- //引入import static org.hamcrest.CoreMatchers.*;
- Assert.assertThat(value,is("lalala"));
- }
-
- }
三、测试Controller类
有3种方法,1可以跟上面一样用@Autowired把Controller注入进来然后调用Controller的方法。参照上方,这里不介绍。
2.用MockMvc模拟的HTTP请求
- package com.sid.controller;
-
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.http.MediaType;
- import org.springframework.test.context.junit4.SpringRunner;
- import org.springframework.test.web.servlet.MockMvc;
- import org.springframework.test.web.servlet.MvcResult;
- import org.springframework.test.web.servlet.ResultActions;
- import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
- import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
- import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
- import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
- import org.springframework.test.web.servlet.setup.MockMvcBuilders;
- import org.springframework.web.context.WebApplicationContext;
- import static org.hamcrest.CoreMatchers.*;
- import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-
-
- /**
- * @Description: Controller层单元测试 注入Spring 上下文的环境到 MockMvc 中 测试时会启动项目
- * @Param:
- * @return:
- * @Author: Sid
- * @Date: 2018-10-24 13:45
- * @since: 1.0
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class UserControllerTest {
-
- /**
- * @Description: 使用MockMvc 模拟HTTP请求 来测试controller
- * MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,
- * 这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
- *
- * // 模拟MVC对象,通过MockMvcBuilders.webAppContextSetup(this.wac).build()初始化。
- * @Param:
- * @return:
- * @Author: Sid
- * @Date: 2018-10-24 13:43
- * @since: 1.0
- */
-
- private MockMvc mvc;
-
- @Autowired
- private WebApplicationContext wac; // 注入WebApplicationContext
-
- /**
- * @Description: 直接注入userController 然后调用userController的方法来测试
- * @Param:
- * @return:
- * @Author: Sid
- * @Date: 2018-10-24 13:44
- * @since: 1.0
- */
- // @Autowired
- // private UserController userController;
-
- @Before
- public void setUp() throws Exception {
- //使用 WebApplicationContext 构建 MockMvc
- this.mvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void addUser() throws Exception {
- MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/add")
- .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
- //form表单格式传参
- .param("id", "4")
- .param("name", "junit test")
- .param("password", "111")
- .param("mobilePhone", "18523980000")
- .characterEncoding("utf-8")
- .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
-
- ResultActions result = mvc.perform(requestBuilder);
-
- MvcResult mvcResult = result.andExpect(MockMvcResultMatchers.status().isOk())
- .andDo(MockMvcResultHandlers.print())
- .andReturn();// 返回执行请求的结果
-
- System.out.println("response------------------:"+mvcResult.getResponse().getContentAsString());
- }
-
- @Test
- public void deleteUser() throws Exception {
- MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/delete")
- .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
- //form表单格式传参
- .param("mobilePhone", "18523980000")
- .characterEncoding("utf-8")
- .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
-
- ResultActions result = mvc.perform(requestBuilder);
-
- MvcResult mvcResult = result.andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(MockMvcResultMatchers.jsonPath("$").value(1))
- .andDo(MockMvcResultHandlers.print())
- .andReturn();// 返回执行请求的结果
-
- System.out.println("response------------------:"+mvcResult.getResponse().getContentAsString());
- }
-
- @Test
- public void updateUser() throws Exception {
- MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/update")
- .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
- //form表单格式传参
- .param("id", "1")
- .param("name", "李沂桀")
- .param("mobilePhone", "185")
- .param("password", "5")
- .characterEncoding("utf-8")
- .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
-
- ResultActions result = mvc.perform(requestBuilder);
-
- MvcResult mvcResult = result.andExpect(MockMvcResultMatchers.status().isOk())
- .andDo(MockMvcResultHandlers.print())
- .andReturn();// 返回执行请求的结果
-
- System.out.println("response------------------:"+mvcResult.getResponse().getContentAsString());
- }
-
- @Test
- public void selectAll() throws Exception {
-
- MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/selectAll")
- .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
- //form表单格式传参
- .param("pageNum", "1")
- .param("pageSize", "5")
- .characterEncoding("utf-8")
- .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
-
- ResultActions result = mvc.perform(requestBuilder);
-
- MvcResult mvcResult = result.andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(jsonPath("list").exists())
- .andExpect(jsonPath("$.list", notNullValue()))
- .andExpect(jsonPath("$.list[0].id", is(1)))
- .andDo(MockMvcResultHandlers.print())
- .andReturn();// 返回执行请求的结果
-
- System.out.println("response------------------:"+mvcResult.getResponse().getContentAsString());
-
-
- }
-
- @Test
- public void getUserByMobilePhone() throws Exception {
-
- MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/getUserByMobilePhone")
- .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
- //form表单格式传参
- .param("mobilePhone", "18523980000")
- .characterEncoding("utf-8")
- .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
-
- ResultActions result = mvc.perform(requestBuilder);
-
- MvcResult mvcResult = result.andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(jsonPath("$", notNullValue()))
- .andExpect(jsonPath("$.name", is("junit test")))
- .andDo(MockMvcResultHandlers.print())
- .andReturn();// 返回执行请求的结果
-
- System.out.println("response------------------:"+mvcResult.getResponse().getContentAsString());
-
-
- }
-
- }
3.用TestRestTemplate 完整HTTP请求测试
- package com.sid.controller;
-
- import com.github.pagehelper.PageInfo;
- import com.sid.model.User;
- import org.hamcrest.Matchers;
- import org.junit.Assert;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.boot.test.web.client.TestRestTemplate;
- import org.springframework.core.ParameterizedTypeReference;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpMethod;
- import org.springframework.http.ResponseEntity;
- import org.springframework.test.context.junit4.SpringRunner;
- import org.springframework.util.LinkedMultiValueMap;
- import org.springframework.util.MultiValueMap;
-
-
- /**
- * @program: springboot
- * @description:
- * @author: Sid
- * @date: 2018-11-15 10:52
- * @since: 1.0
- **/
- @RunWith(SpringRunner.class)
- //开启一个随机的可用端口
- @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
- public class TestRestTemplateTest {
- @Autowired
- private TestRestTemplate restTemplate;
-
- @Test
- public void listAll() {
- String url = "/user/selectAll";
- // 封装入参数,不要替换为Map与HashMap,否则参数无法传递
- MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
- paramMap.add("pageNum", 1);
- paramMap.add("pageSize", 5);
- HttpHeaders headers = new HttpHeaders();
- HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(paramMap,headers);
-
-
- // 1、使用postForObject请求接口
- PageInfo<User> result = restTemplate.postForObject(url, paramMap, PageInfo.class);
- System.out.println("result1==================" + result.getList());
-
- // 2、使用postForEntity请求接口
- ResponseEntity<PageInfo> response2 = restTemplate.postForEntity(url, httpEntity, PageInfo.class);
- System.out.println("result2====================" + response2.getBody().getList());
-
- // 3、使用exchange请求接口
- //设置接受参数的类型 只有用exchange+ParameterizedTypeReference接收到的pageInfo中的List是user类,上面两种方式接收到的都是个LinkedList
- ParameterizedTypeReference<PageInfo<User>> type = new ParameterizedTypeReference<PageInfo<User>>() {};
- ResponseEntity<PageInfo<User>> response3 = restTemplate.exchange(url, HttpMethod.POST, httpEntity, type);
- System.out.println("result3====================" + response3.getBody().getList());
- Assert.assertThat(response3.getBody().getList(), Matchers.notNullValue());
- }
-
- }
四、常用注解介绍
@Before:初始化方法
@After:释放资源
@Test:测试方法(包括:期望异常和超时时间)
@Test(timeout = 1000),超时会失败。
@Test(expected = NullPointerException.class) 希望抛出空指针异常
@Ignore:忽略的测试方法
@BeforeClass:针对所有测试,只执行一次,且必须为static void
@AfterClass:针对所有测试,只执行一次,且必须为static void
@RunWith:可以更改测试运行器
执行顺序:
@BeforeClass ==> @Before ==> @Test ==> @After ==> @AfterClass
@SpringBootTest会加载spring的上下文,这样可以使用@Autowired注入Bean
五、参数化测试
1.使用parameterized入参
每一组参数执行一次test的入参
- package com.sid.controller;
-
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.junit.runners.Parameterized;
-
- import java.util.Arrays;
- import java.util.List;
-
- import static org.hamcrest.Matchers.is;
- import static org.junit.Assert.assertThat;
-
- /**
- * @program: springboot
- * @description: 参数化测试
- * @author: Sid
- * @date: 2018-11-15 10:33
- * @since: 1.0
- **/
-
- //1.需要使用Parameterized运行器
- @RunWith(Parameterized.class)
- public class ParameterTest {
- // 2.声明变量存放预期值和测试数据
- private String firstName;
- private String lastName;
-
- //3.声明一个返回值 为Collection的公共静态方法,并使用@Parameters进行修饰
- @Parameterized.Parameters //
- public static List<Object[]> param() {
- // 两个测试用例
- return Arrays.asList(new Object[][]{{"Sid", "Lee"}, {"Tom", "Cat"}});
- }
-
- //4.为测试类声明一个带有参数的公共构造函数,并在其中为之声明变量赋值
- public ParameterTest(String firstName, String lastName) {
- this.firstName = firstName;
- this.lastName = lastName;
- }
- // 5. 进行测试,发现它会将所有的测试用例测试一遍
- @Test
- public void test() {
- String name = firstName + " " + lastName;
- assertThat("Sid Lee", is(name));
- }
-
- }

2.使用Theories入参
提供一组参数的排列组合值作为待测方法的输入参数。
使用Theories这个Runner的时候,待测方法可以拥有输入参数,而这在其它的Runner中的测试方法是不行的。
- package com.sid.controller;
-
- import org.junit.experimental.theories.DataPoint;
- import org.junit.experimental.theories.DataPoints;
- import org.junit.experimental.theories.Theories;
- import org.junit.experimental.theories.Theory;
- import org.junit.runner.RunWith;
-
- /**
- * @program: springboot
- * @description:
- * @author: Sid
- * @date: 2018-11-15 11:41
- * @since: 1.0
- **/
- @RunWith(Theories.class)
- public class TestTheories {
- @DataPoint
- public static String nameValue1 = "Sid";
- @DataPoint
- public static String nameValue2 = "Pencil";
- @DataPoint
- public static int ageValue1 = 27;
- @DataPoint
- public static int ageValue2 = 18;
-
- //也可以用这种方式提供参数
- // @DataPoints
- // public static String[] names = {"Sid", "Pencil"};
- // @DataPoints
- // public static int[] ages = {27, 18};
-
- @Theory
- public void testMethod(String name, int age){
- System.out.println(String.format("%s's age is %s", name, age));
- }
- }
结果:

本文介绍如何在IDEA中自动化生成测试类,使用Spring Boot进行Service和Controller层的单元测试,涵盖MockMvc和TestRestTemplate的使用,以及常见的测试注解和参数化测试方法。
641

被折叠的 条评论
为什么被折叠?



