1.版本说明
SpringBoot 2.4 以上版本移除了默认对Vintage的依赖。如果需要兼容junit4需要自行引入(不能使用junit4的功能@Test)
2.引入junit5依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- SpringBoot整合Junit以后。
- 编写测试方法.
- @Test标注(注意需要使用junit5版本的注解)
- Junit类具有Spring的功能, @Autowired、比如@Transactional标注测试方法,测试完成后自动回滚.
@SpringBootTest
class Demo04ApplicationTests {
@Test
void contextLoads() {
}
}
3.junit5的常用注解
@DisplayName:为测试类或者测试方法设置展现名称
@DisplayName("junit5功能测试类")
public class Junit5Test {
@DisplayName("测试displayname注解")
@Test
public void test1() {
System.out.println("小张");
}
}
- @BeforeEach:表示每个单元测试之前执行(每个测试都会执行)
- @AfterEach:表示每个单元测试之后执行(每个测试都会执行)
- @BeforeAll:表示所有单元测试之前执行(仅执行一次)
- @AfterAll:表示所有单元测试之后执行(仅执行一次)
注意:@BeforeAll与@AfterAll所表示的方法为静态方法
@BeforeEach
void testBeforeEach(){
System.out.println("测试即将开始=====");
}
@AfterEach
void testAfterEach(){
System.out.println("测试结束====");
}
@BeforeAll
static void testBeforeAll(){
System.out.println("所有测试方法即将开始");
}
@AfterAll
static void testAfterAll(){
System.out.println("所有测试方法结束");
}
@Disabled:表示禁用测试
@Disabled
@DisplayName("测试一")
@Test
public void test1() {
System.out.println("测试-------小张");
}
4.断言
- 断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。
- 这些断言方法都是org.junit.jupiter.api.Assertions的静态方法。
- 检查业务逻辑返回的数据是否合理。
- 所有的测试运行结束以后,会有一个详细的测试报告;
4.1断言api
api都在此包下:org.junit.jupiter.api.Assertions
- assertEquals:判断两个对象或两个原始类型是否相等
- assertNotEquals:判断两个对象或两个原始类型是否不相等
- assertSame:判断两个对象引用是否指向同一个对象
- assertNotSame:判断两个对象引用是否指向不同的对象
- assertTrue:判断给定的布尔值是否为 true
- assertFalse:判断给定的布尔值是否为false
- assertNull:判断给定的对象引用是否为null
- assertNotNull:判断给定的对象引用是否不为 null
4.2简单断言
assertEquals(预期值,实际值,自定义错误信息)
@DisplayName("测试断言")
@Test
public void testSimpleAssertions(){
int cal = cal(1, 2);
assertEquals(5,cal,"结果计算失败");
}
int cal(int i,int j){
return i+j;
}
注意:前面断言失败,后面的代码都不会执行 。
4.3数组断言
@Test
public void test2(){
int[] arr1=new int[]{1,2,3}; //期望的
int[] arr2=new int[]{4,5,6}; //实际的
assertArrayEquals(arr1,arr2,"两个数组不相等");
}
4.4组合断言
- 通过lambda表达式进行。
- 只有全部断言通过,才能继续进行
@DisplayName("组合断言")
@Test
public void test3() {
assertAll("test",
() -> assertTrue(true && true),
()->assertEquals(20,2,"两值不等"));
}
4.5异常断言
预期值会出现异常,看实际值是否与预期值一样
@Test
@DisplayName("异常断言")
public void test4() {
assertThrows(ArithmeticException.class, () -> {
int a = 10 / 2;
}, "与预期值不符");
}
4.6超时断言
设置预期的超时时间,看实际值是否与预期值相等
@Test
@DisplayName("超时异常")
public void test5(){
assertTimeout(Duration.ofMillis(3000),()->Thread.sleep(4000),"与预期超时时间不一致");
}
4.7快速失败
通过fail方法直接使得测试失败
@Test
@DisplayName("fail")
public void test6() {
fail("测试失败");
}
5.前置条件
类似于断言,不同之处在于不满足的断言会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止。前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。
@Test
@DisplayName("测试前置条件")
public void test7(){
Assumptions.assumeTrue(true,"结果不是true");
System.out.println("我是小张");
}
如果测试通过会显示 ---我是小张
如果测试失败,不会报错
6.嵌套测试
下面测试test1,发现通过,说明stack为空!!!
- 嵌套测试,外层的@Test不能驱动内层的@Before(After)Each/ @Before(After)ALL之类的方法提前运行
Stack<Object> stack;
@Test
@DisplayName("new stack")
public void test1() {
new Stack<>();
//嵌套测试,外层的Test不能驱动内层的 @BeforeEach/ @BeforeALl之类的方法提前运行
assertNull(stack);
}
//嵌套
@Nested
@DisplayName("嵌套")
class newStack {
@BeforeEach
public void createStack() {
stack = new Stack<>();
}
}
- 嵌套测试,内层的@Test可以驱动外层的@Before(After)Each/ @Before(After)ALL之类的方法提前运行
Stack<Object> stack;
//外层提定义stack
@DisplayName("new stack")
@BeforeEach
public void test1() {
stack= new Stack<>();
}
//嵌套
@Nested
@DisplayName("嵌套")
class newStack {
@BeforeEach
public void createStack() {
String name = "小张";
stack.push(name);
}
@Test
@DisplayName("栈不为空")
public void test2() {
assertFalse(stack.isEmpty());
}
}
}
7.参数化测试
不用不同的参数值,来测试同一个方法
7.1各种注解
不在使用@Test注解,而是使用@ParameterizedTest
- @ValueSource:为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型@NullSource: 表示为参数化测试提供一个null的入参
- @EnumSource:表示为参数化测试提供一个枚举入参
- @CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参
- @MethodSource:表示读取指定方法的返回值作为参数化测试入参【静态方法】
7.2@ValueSource
指定参数来源 :@ValueSource(ints = {1,2,3,4,5})
@ParameterizedTest
@DisplayName("参数化测试1")
@ValueSource(ints = {1,2,3,4,5})
public void test1(int i){
System.out.println(i);
}
7.3@MethodSource
读取指定方法的返回值,注意方法为static权限
@ParameterizedTest
@DisplayName("参数化测试2")
@MethodSource("name")
public void test2(String name){
System.out.println(name);
}
static String[] name(){
return new String[]{"小张1","小张2","小张3"};
}