1.前置条件
- JUnit 5中的前置条件(assumptions【假设】)类似于断言,不同之处在于不满足的断言assertions会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止。
- 前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。
- assumeTrue 和 assumFalse 确保给定的条件为 true 或 false,不满足条件会使得测试执行终止。
- assumingThat 的参数是表示条件的布尔值和对应的 Executable 接口的实现对象。只有条件满足时,Executable
对象才会被执行;当条件不满足时,测试执行并不会终止。
JTest5
package com.limi.springboottest2;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.Duration;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
@SpringBootTest
public class JTest5 {
private final String environment = "DEV";
@Test
@DisplayName("simple")
public void simpleAssume() {
System.out.println(0);
assumeTrue(Objects.equals(this.environment, "DEV1"));
System.out.println(1);
assumeFalse(() -> Objects.equals(this.environment, "PROD"));
System.out.println(2);
}
@Test
@DisplayName("assume then do")
public void assumeThenDo() {
System.out.println(3);
assumingThat(
Objects.equals(this.environment, "DEV"),
() -> System.out.println("In DEV")
);
System.out.println(4);
}
}
我们对比一下断言
JTest5
@SpringBootTest
public class JTest5 {
@Test
public void simple() {
assertEquals(4, 1 + 2, "simple math");
System.out.println(1);
}
@Test
public void simple1() {
assertNotEquals(3, 1 + 1);
System.out.println(2);
}
}
2.嵌套测试
- JUnit 5 可以通过 Java 中的内部类和@Nested注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach和@AfterEach注解,而且嵌套的层次没有限制。但是不能使用@BeforeAll和@AfterAll
- 外层类的测试方法不会触发内层类的@BeforeEach
- 内层类的测试方法可以触发外层类的@BeforeEach
package com.limi.springboottest2;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TestDemo {
@BeforeEach
void test01() {
System.out.println("1层-1");
}
@Test
void test02() {
System.out.println("1层-2"); //外层类的测试方法不会触发内层类的@BeforeEach
}
@Nested
class A2 {
@BeforeEach
void test1() {
System.out.println("2层-1");
}
@Nested
class A3 {
@BeforeEach
void test2() {
System.out.println("3层-1");
}
@Test
void test21() {
System.out.println("3层-2"); //内层类的测试方法可以触发外层类的@BeforeEach
}
}
}
}
执行最外层类的测试方法est02
执行最内层内的测试方法test21
执行整个测试类
3.参数化测试
官方文档 - Parameterized Tests
参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。
利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。
利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。
- @ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型
- @NullSource: 表示为参数化测试提供一个null的入参
- @EnumSource: 表示为参数化测试提供一个枚举入参
- @CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参
- @MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)
当然如果参数化测试仅仅只能做到指定普通的入参还达不到让我觉得惊艳的地步。让我真正感到他的强大之处的地方在于他可以支持外部的各类入参。如:CSV,YML,JSON 文件甚至方法的返回值也可以作为入参。只需要去实现ArgumentsProvider接口,任何外部文件都可以作为它的入参。
@ValueSource
public @interface ValueSource {
short[] shorts() default {};
byte[] bytes() default {};
int[] ints() default {};
long[] longs() default {};
float[] floats() default {};
double[] doubles() default {};
char[] chars() default {};
boolean[] booleans() default {};
String[] strings() default {};
Class<?>[] classes() default {};
}
可以看到@ValueSource传入的是数组类型
测试类TestDemo
package com.limi.springboottest2;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TestDemo {
@ParameterizedTest
@ValueSource(strings = {"one", "two", "three"})
void test01(String str) {
System.out.println(str);
}
}