java-junit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

JUnit 5+ Best Practices

JUnit 5+ 最佳实践

Your goal is to help me write effective unit tests with JUnit 5, covering both standard and data-driven testing approaches.
本文旨在帮助你使用JUnit 5编写高效的单元测试,涵盖标准测试和数据驱动测试两种方法。

Project Setup

项目设置

  • Use a standard Maven or Gradle project structure.
  • Place test source code in
    src/test/java
    .
  • Include dependencies for
    junit-jupiter-api
    ,
    junit-jupiter-engine
    , and
    junit-jupiter-params
    for parameterized tests.
  • Use build tool commands to run tests:
    mvn test
    or
    gradle test
    .
  • 使用标准的Maven或Gradle项目结构。
  • 将测试源代码放置在
    src/test/java
    目录下。
  • 引入
    junit-jupiter-api
    junit-jupiter-engine
    以及用于参数化测试的
    junit-jupiter-params
    依赖。
  • 使用构建工具命令运行测试:
    mvn test
    gradle test

Test Structure

测试结构

  • Test classes should have a
    Test
    suffix, e.g.,
    CalculatorTest
    for a
    Calculator
    class.
  • Use
    @Test
    for test methods.
  • Follow the Arrange-Act-Assert (AAA) pattern.
  • Name tests using a descriptive convention, like
    methodName_should_expectedBehavior_when_scenario
    .
  • Use
    @BeforeEach
    and
    @AfterEach
    for per-test setup and teardown.
  • Use
    @BeforeAll
    and
    @AfterAll
    for per-class setup and teardown (must be static methods).
  • Use
    @DisplayName
    to provide a human-readable name for test classes and methods.
  • 测试类应带有
    Test
    后缀,例如针对
    Calculator
    类的测试类命名为
    CalculatorTest
  • 为测试方法添加
    @Test
    注解。
  • 遵循准备-执行-断言(AAA)模式。
  • 使用描述性命名规则为测试命名,例如
    methodName_should_expectedBehavior_when_scenario
  • 使用
    @BeforeEach
    @AfterEach
    实现测试方法级别的前置准备和后置清理。
  • 使用
    @BeforeAll
    @AfterAll
    实现测试类级别的前置准备和后置清理(必须为静态方法)。
  • 使用
    @DisplayName
    为测试类和方法提供易读的名称。

Standard Tests

标准测试

  • Keep tests focused on a single behavior.
  • Avoid testing multiple conditions in one test method.
  • Make tests independent and idempotent (can run in any order).
  • Avoid test interdependencies.
  • 保持测试聚焦于单一行为。
  • 避免在一个测试方法中测试多个条件。
  • 确保测试独立且幂等(可按任意顺序运行)。
  • 避免测试之间存在依赖关系。

Data-Driven (Parameterized) Tests

数据驱动(参数化)测试

  • Use
    @ParameterizedTest
    to mark a method as a parameterized test.
  • Use
    @ValueSource
    for simple literal values (strings, ints, etc.).
  • Use
    @MethodSource
    to refer to a factory method that provides test arguments as a
    Stream
    ,
    Collection
    , etc.
  • Use
    @CsvSource
    for inline comma-separated values.
  • Use
    @CsvFileSource
    to use a CSV file from the classpath.
  • Use
    @EnumSource
    to use enum constants.
  • 使用
    @ParameterizedTest
    标记参数化测试方法。
  • 使用
    @ValueSource
    传入简单字面量值(字符串、整数等)。
  • 使用
    @MethodSource
    引用提供测试参数的工厂方法,参数格式可为
    Stream
    Collection
    等。
  • 使用
    @CsvSource
    传入内联的逗号分隔值。
  • 使用
    @CsvFileSource
    从类路径中读取CSV文件作为测试参数。
  • 使用
    @EnumSource
    传入枚举常量作为测试参数。

Assertions

断言

  • Use the static methods from
    org.junit.jupiter.api.Assertions
    (e.g.,
    assertEquals
    ,
    assertTrue
    ,
    assertNotNull
    ).
  • For more fluent and readable assertions, consider using a library like AssertJ (
    assertThat(...).is...
    ).
  • Use
    assertThrows
    or
    assertDoesNotThrow
    to test for exceptions.
  • Group related assertions with
    assertAll
    to ensure all assertions are checked before the test fails.
  • Use descriptive messages in assertions to provide clarity on failure.
  • 使用
    org.junit.jupiter.api.Assertions
    中的静态方法(例如
    assertEquals
    assertTrue
    assertNotNull
    )。
  • 若需要更流畅易读的断言方式,可考虑使用AssertJ库(语法如
    assertThat(...).is...
    )。
  • 使用
    assertThrows
    assertDoesNotThrow
    测试异常场景。
  • 使用
    assertAll
    对相关断言进行分组,确保所有断言在测试失败前都会被检查。
  • 在断言中添加描述性消息,以便在测试失败时提供清晰的原因说明。

Mocking and Isolation

模拟与隔离

  • Use a mocking framework like Mockito to create mock objects for dependencies.
  • Use
    @Mock
    and
    @InjectMocks
    annotations from Mockito to simplify mock creation and injection.
  • Use interfaces to facilitate mocking.
  • 使用Mockito等模拟框架为依赖项创建模拟对象。
  • 使用Mockito的
    @Mock
    @InjectMocks
    注解简化模拟对象的创建和注入。
  • 使用接口以便于模拟操作。

Test Organization

测试组织

  • Group tests by feature or component using packages.
  • Use
    @Tag
    to categorize tests (e.g.,
    @Tag("fast")
    ,
    @Tag("integration")
    ).
  • Use
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    and
    @Order
    to control test execution order when strictly necessary.
  • Use
    @Disabled
    to temporarily skip a test method or class, providing a reason.
  • Use
    @Nested
    to group tests in a nested inner class for better organization and structure.
  • 按功能或组件使用包对测试进行分组。
  • 使用
    @Tag
    对测试进行分类(例如
    @Tag("fast")
    @Tag("integration")
    )。
  • 当确实需要控制测试执行顺序时,使用
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    @Order
    注解。
  • 使用
    @Disabled
    临时跳过某个测试方法或类,并提供跳过原因。
  • 使用
    @Nested
    将测试分组到嵌套内部类中,以实现更好的组织和结构。