概述:
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
JUnit Platform: Junit Platform是在JVM上启动测试框架的基础
Unit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部包含了一个测试引擎,用于在Junit Platform上运行
JUnit Vintage: 测试引擎
注是springboot2.4版本及之后引入的功能
使用:
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.Spring的JUnit 5的基本单元测试模板
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;//注意不是org.junit.Test(这是JUnit4版本的)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringBootApplicationTests {
@Autowired
private Component component;
@Test
//@Transactional 标注后连接数据库有回滚功能
public void contextLoads() {
Assertions.assertEquals(5, component.getFive());
}
}
3.单元测试常用的基础测试注解
import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
@DisplayName("junit5简单基础功能测试类")
@SpringBootTest
public class Junit5Test {
@DisplayName("测试方法1")
@Test
void test1() {
System.out.println(1);
}
@DisplayName("测试方法2")
@Test
void test2() {
System.out.println(2);
}
@Disabled // 标了这个注解的测试方法不执行
@DisplayName("测试@Disabled")
@Test
void test3() {
System.out.println("Disabled");
}
@RepeatedTest(2) // 重复执行2次
@DisplayName("测试@RepeatedTest重复执行多次")
@Test
void test4() {
System.out.println(555);
}
@DisplayName("测试任务超时")
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
@Test
void testTimeout() throws InterruptedException {
System.out.println("测试任务超时");
Thread.sleep(300);
}
@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("所有测试已经结束了...");
}
}
断言测试
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("断言测试")
@SpringBootTest
public class AssertTest {
@Test
@DisplayName("简单断言测试")
public void simple() {
assertEquals(3, 1 + 2, "simple math");
assertNotEquals(3, 1 + 1);
assertNotSame(new Object(), new Object());
Object obj = new Object();
assertSame(obj, obj);
assertFalse(1 > 2);
assertTrue(1 < 2);
assertNull(null);
assertNotNull(new Object());
}
@Test
@DisplayName("数组断言测试")
public void array() {
assertArrayEquals(new int[]{1, 2}, new int[] {1, 2});
}
// assertAll()方法接受多个 org.junit.jupiter.api.Executable 函数式接口的实例作为要验证的断言,可以通过 lambda 表达式很容易的提供这些断言
@Test
@DisplayName("组合断言测试")
public void all() {
assertAll("Math",
() -> assertEquals(2, 1 + 1),
() -> assertTrue(1 > 0)
);
}
@Test
@DisplayName("异常断言测试")
public void exceptionTest() {
ArithmeticException exception = Assertions.assertThrows(
//扔出断言异常
ArithmeticException.class, () -> System.out.println(1 % 0)
);
}
@Test
@DisplayName("超时断言测试")
public void timeoutTest() {
//如果测试方法时间超过1s将会异常
Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
}
@Test
@DisplayName("快速失败")
public void shouldFail() {
fail("This should fail");
}
}
参数化测试
import org.apache.commons.lang.StringUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import java.util.stream.Stream;
/**
* 参数化测试
*/
@DisplayName("参数化测试")
public class ParameterTest {
// 静态方法在项目启动时加载
static Stream<String> method() {
return Stream.of("apple", "banana");
}
@ParameterizedTest
@MethodSource("method") //指定方法名
@DisplayName("测试@MethodSource的用法")
public void testWithExplicitLocalMethodSource(String name) {
System.out.println(name);
Assertions.assertNotNull(name);
}
@ParameterizedTest
@ValueSource(strings = {"one", "two", "three"})
@DisplayName("测试@ValueSource的用法")
public void valueSourceTest(String string) {
System.out.println(string);
Assertions.assertTrue(StringUtils.isNotBlank(string));
}
@ParameterizedTest
@NullSource // 提供一个空参Null
@DisplayName("测试@NullSource的用法")
public void nullSourceTest(String str) {
System.out.println(str);
Assertions.assertTrue(StringUtils.isBlank(str));
}
}