返回

JUnit4 与 JUnit5 的测试模板对比

开发工具

正文

JUnit 和 JUnit5 是两种流行的 Java 单元测试框架,其中测试模板是一个重要的概念。它允许您创建可重用的测试代码,以便您可以轻松地测试不同输入或条件。

JUnit4 中的测试模板

在 JUnit4 中,可以使用 @TestTemplate 注解来标记测试模板方法。该方法必须返回一个 TestTemplateInvocationContext 对象,其中包含要执行的测试用例。

@TestTemplate 注解可以与一个或多个 TestTemplateInvocationContextProvider 扩展一起使用。这些扩展用于为测试模板方法提供数据。

例如,以下代码展示了如何使用 @TestTemplate 注解和 TestTemplateInvocationContextProvider 扩展来测试一个计算阶乘的函数:

import org.junit.TestTemplate;
import org.junit.TestTemplateInvocationContext;

public class FactorialTest {

    @TestTemplate
    public void testFactorial(TestTemplateInvocationContext context) {
        int n = context.getValue("input");
        int expected = context.getValue("expected");
        assertEquals(expected, factorial(n));
    }

    private static int factorial(int n) {
        if (n == 0) {
            return 1;
        } else {
            return n * factorial(n - 1);
        }
    }

    public static class FactorialTestInvocationContextProvider implements TestTemplateInvocationContextProvider {

        @Override
        public TestTemplateInvocationContext forTestTemplate(ExtensionContext context) {
            return new TestTemplateInvocationContext() {

                @Override
                public String getDisplayName(int index) {
                    return "testFactorial(" + index + ")";
                }

                @Override
                public Object getValue(String parameterName) {
                    switch (parameterName) {
                        case "input":
                            return index;
                        case "expected":
                            return factorial(index);
                        default:
                            throw new IllegalArgumentException("Unknown parameter: " + parameterName);
                    }
                }
            };
        }
    }
}

当您运行此测试时,JUnit4 将使用 FactorialTestInvocationContextProvider 扩展为 testFactorial 方法生成多个测试用例。每个测试用例都将使用不同的输入值,并且预期值将根据输入值计算。

JUnit5 中的测试模板

在 JUnit5 中,测试模板的概念有所变化。在 JUnit5 中,您可以使用 @ParameterizedTest 注解来标记测试模板方法。该方法必须接受一个 ArgumentsSource 参数,该参数用于提供测试用例的数据。

@ParameterizedTest 注解还可以与一个或多个 TestTemplateInvocationContextProvider 扩展一起使用。这些扩展用于为测试模板方法提供数据。

以下代码展示了如何使用 @ParameterizedTest 注解和 TestTemplateInvocationContextProvider 扩展来测试一个计算阶乘的函数:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsSource;

public class FactorialTest {

    @ParameterizedTest
    @ArgumentsSource(FactorialTestInvocationContextProvider.class)
    void testFactorial(int n, int expected) {
        assertEquals(expected, factorial(n));
    }

    private static int factorial(int n) {
        if (n == 0) {
            return 1;
        } else {
            return n * factorial(n - 1);
        }
    }

    public static class FactorialTestInvocationContextProvider implements ArgumentsSource {

        @Override
        public Stream<Arguments> provideArguments(ExtensionContext context) {
            return Stream.of(
                Arguments.of(0, 1),
                Arguments.of(1, 1),
                Arguments.of(2, 2),
                Arguments.of(3, 6),
                Arguments.of(4, 24)
            );
        }
    }
}

当您运行此测试时,JUnit5 将使用 FactorialTestInvocationContextProvider 扩展为 testFactorial 方法生成多个测试用例。每个测试用例都将使用不同的输入值和预期值。

JUnit4 和 JUnit5 中测试模板的对比

JUnit4 和 JUnit5 中的测试模板在使用上有一些差异。以下是对这两者的一些对比:

  • 注解: JUnit4 使用 @TestTemplate 注解来标记测试模板方法,而 JUnit5 使用 @ParameterizedTest 注解来标记测试模板方法。
  • 参数: JUnit4 的测试模板方法必须返回一个 TestTemplateInvocationContext 对象,其中包含要执行的测试用例。JUnit5 的测试模板方法必须接受一个 ArgumentsSource 参数,该参数用于提供测试用例的数据。
  • 扩展: JUnit4 和 JUnit5 都可以使用 TestTemplateInvocationContextProvider 扩展来为测试模板方法提供数据。

总结

JUnit4 和 JUnit5 中的测试模板都是非常强大的工具,可以帮助您轻松地测试不同输入或条件。如果您正在寻找一种方法来简化您的测试代码,那么测试模板是一个非常好的选择。