JUnit5代码段

引入 mvn 依赖

    <!-- JUnit5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.5.2</version>
        <scope>test</scope>
    </dependency>
    <!-- JUnit4 的兼容包 -->
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.5.2</version>
        <scope>test</scope>
    </dependency>
    <!-- JUnit5 参数化测试 API -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-params</artifactId>
        <version>5.5.2</version>
        <scope>test</scope>
    </dependency>

JUnit5常用注解

import org.junit.jupiter.api.*;

@Tag("标签1")
@DisplayName("使用基本注解")
public class BaseAnnotation {

    @BeforeAll
    public static void beforeAll() {
        System.out.println("仅在第一个测试方法之前执行,且只执行一次");
    }

    @AfterAll
    public static void afterAll() {
        System.out.println("仅在第一个测试方法之后执行,且只执行一次");
    }

    @BeforeEach
    public void beforeEach() {
        System.out.println("每个测试方法前都会执行");
    }

    @AfterEach
    public void afterEach() {
        System.out.println("每个测试方法后都会执行");
    }

    @Tag("标签1")
    @DisplayName("测试方法1")
    @Test
    void displayName() {
        System.out.println("测试方法1");
    }

    @Tag("标签1")
    @DisplayName("测试方法2")
    @Test
    void testForthTest() {
        System.out.println("测试方法2");
    }

    @Tag("标签2")
    @DisplayName("标签2-方法1")
    @Test
    void testSecondTest() {
        System.out.println("我的第二个测试开始测试");
    }

    @Tag("标签2")
    @Disabled
    @DisplayName("标签2-方法2-@disabled")
    @Test
    void disabled() {
        System.out.println("@Disabled 禁用测试方法");
    }

    @DisplayName("重复测试方法")
    @RepeatedTest(2)
    void repeatTest(){
        System.out.println("重复测试执行");
    }

    @Nested
    @DisplayName("嵌套-测试类")
    class FirstNestTest {
        @DisplayName("嵌套-测试方法A1")
        @Test
        void test() {
            System.out.println("测试方法A1");
        }
    }

}

JUnit5断言与假设

import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.*;

/**
 * {@link org.junit.jupiter.api.Assertions}
 * {@link org.junit.jupiter.api.Assumptions}
 */
@DisplayName("使用断言与假设工具")
public class AssertUtil {

    /**
     * 断言:当某一断言不符合预期结果时会抛出 AssertionError extends Error 终止当前线程。
     */
    @Test
    void assertions(){

        /* java 中的 boolean 值断言关键字 assert */
        boolean assertable = Math.random() != Math.random();
        assert assertable : "impossible is nothing!!!";

        /* JUnit5 提供的断言方法 org.junit.jupiter.api.Assertions.* */

        /* 断言信息 */
        assertTrue(true,"不为 true 时输出的信息");

        /* 值断言 */
        assertTrue(true);
        assertFalse(false);
        assertNull(null);
        assertNotNull(new Object());

        assertEquals(5,5);
        assertNotEquals(new int[]{1,2,3,4,5},new int[]{1,2,3,4,5});
        assertArrayEquals(new int[]{1,2,3,4,5},new int[]{1,2,3,4,5});

        assertSame(1,1);
        assertNotSame(new int[]{1,2,3,4,5},new int[]{1,2,3,4,5});

        /* 分组断言 */
        assertAll(
                ()->{ System.out.println("批量断言-0"); },
                ()->{ System.out.println("批量断言-1"); },
                ()->{ System.out.println("批量断言-2"); }
        );

        /* 异常或失败断言 */
        assertThrows(Exception.class,()->{throw new Exception("抛出异常");});
        assertDoesNotThrow(()->{System.out.println("不抛出异常");});

        /* 同步的超时断言 */
        assertTimeout(Duration.ofSeconds(4),()->{
            Thread.sleep(3000);
        });
        /* 抢断的超时断言 */
        assertTimeoutPreemptively(Duration.ofSeconds(4),()->{
            Thread.sleep(3000);
        });
    }
    
    /**
     * 假设:通过抛出 IncompleteExecutionException extends RuntimeException 异常结束执行,该异常由 JUnit 处理。
     * 所以 Assumptions 不会导致测试失败。
     */
    @Test
    void assumptions() {
        //System.getenv().forEach((key, value) -> System.out.println(key + " -> " + value));
        Assumptions.assumeTrue(!"Windows_NT".equals(System.getenv("OS")));
        Assumptions.assumeTrue("Windows_NT".equals(System.getenv("OS")));
        System.out.println("Assumptions");
    }
}

JUnit5 参数化测试

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;

import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE;
import static org.junit.jupiter.params.provider.EnumSource.Mode.MATCH_ALL;

@DisplayName("参数化测试")
public class ParamsTest {

    @DisplayName("@ValueSource 值参数")
    @ValueSource(strings = {"Effective Java","Code Complete","Clean Code"})
    @ParameterizedTest
    void valueSourceTest(String str){
        System.out.println(str);
    }

    @DisplayName("@CsvSource CSV格式字符串")
    @CsvSource(value = {"1@one","2@two","3@three"},delimiter = '@')
    @ParameterizedTest
    void csvSourceTest(long id,String name){
        System.out.printf("id: %d, name: %s\n",id,name);
    }

    @DisplayName("@CsvFileSource CSV文件")
    @CsvFileSource(resources = "/test.csv",  delimiter = ',' )
    @ParameterizedTest
    void testDataFromCsv(long id, String name) {
        System.out.printf("id: %d, name: %s\n", id, name);
/*
test.csv
1,one
2,two
3,three
*/
    }

    @DisplayName("@EnumSource 枚举类")
    @EnumSource(value = TimeUnit.class, mode = EXCLUDE, names = { "DAYS", "HOURS" })
    @ParameterizedTest
    void testWithEnumSourceExclude(TimeUnit timeUnit) {
        EnumSet<TimeUnit> timeUnitEnumSet = EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS);
        assertFalse(timeUnitEnumSet.contains(timeUnit));
    }

    @EnumSource(value = TimeUnit.class, mode = MATCH_ALL, names = "^(M|N).+SECONDS$")
    @ParameterizedTest
    void testWithEnumSourceExcludeRegEx(TimeUnit timeUnit) {
        assertFalse(EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS).contains(timeUnit));
    }

    @MethodSource("stringProvider")
    @ParameterizedTest
    void testWithSimpleMethodSource(String argument) {
        assertNotNull(argument);
    }

    static Stream<String> stringProvider() {
        return Stream.of("foo", "bar");
    }

    @ArgumentsSource(ArgumentsProviderImpl.class)
    @ParameterizedTest
    void testWithArgumentSource(String arg){
        assertNotNull(arg);
    }

    static class ArgumentsProviderImpl implements ArgumentsProvider{
        @Override
        public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
            return  Stream.of("foo", "bar").map(Arguments::of);
        }
    }
}

 

上一篇:LeetCode 0001 Two Sum


下一篇:LeetCode 1996. 游戏中弱角色的数量