1.安装插件JUnitGenerator V2.0
File---->Settings---->Browse Repositories
2.安装好后把JUnit和JUnitGenerator V2.0一起勾上
3.配置插件
把package上test.前缀去掉
配置测试类生成的地址
${SOURCEPATH}/../../test/java/${PACKAGE}/${FILENAME}
4.对着要生成的类
@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"));
}
}
有3种方法,1可以跟上面一样用@Autowired把Controller注入进来然后调用Controller的方法。参照上方,这里不介绍。
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());
}
}
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 paramMap = new LinkedMultiValueMap<>();
paramMap.add("pageNum", 1);
paramMap.add("pageSize", 5);
HttpHeaders headers = new HttpHeaders();
HttpEntity> httpEntity = new HttpEntity<>(paramMap,headers);
// 1、使用postForObject请求接口
PageInfo result = restTemplate.postForObject(url, paramMap, PageInfo.class);
System.out.println("result1==================" + result.getList());
// 2、使用postForEntity请求接口
ResponseEntity response2 = restTemplate.postForEntity(url, httpEntity, PageInfo.class);
System.out.println("result2====================" + response2.getBody().getList());
// 3、使用exchange请求接口
//设置接受参数的类型 只有用exchange+ParameterizedTypeReference接收到的pageInfo中的List是user类,上面两种方式接收到的都是个LinkedList
ParameterizedTypeReference> type = new ParameterizedTypeReference>() {};
ResponseEntity> 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
每一组参数执行一次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
提供一组参数的排列组合值作为待测方法的输入参数。
使用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));
}
}
结果: