一、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));
-
}
-
}
结果: