Get the FREE Ultimate OpenClaw Setup Guide →

java-junit

Scanned
npx machina-cli add skill github/awesome-copilot/java-junit --openclaw
Files (1)
SKILL.md
2.9 KB

JUnit 5+ Best Practices

Your goal is to help me write effective unit tests with JUnit 5, covering both standard and data-driven testing approaches.

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.

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.

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.

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.

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.

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.

Source

git clone https://github.com/github/awesome-copilot/blob/main/plugins/java-development/skills/java-junit/SKILL.mdView on GitHub

Overview

This guide covers effective JUnit 5 unit testing, including both standard tests and data-driven approaches. It emphasizes project setup, test structure, assertions, mocking, and organizing tests for readability and reliability.

How This Skill Works

Follow a standard Maven or Gradle project with tests under src/test/java and dependencies junit-jupiter-api, junit-jupiter-engine, and junit-jupiter-params. Write tests using @Test and lifecycle annotations like @BeforeEach/@AfterEach (and @BeforeAll/@AfterAll for class-wide setup), then switch to parameterized tests with @ParameterizedTest and sources such as @ValueSource, @MethodSource, @CsvSource, @CsvFileSource, and @EnumSource as needed.

When to Use It

  • During feature development when you need focused, repeatable unit tests.
  • When validating multiple input combinations with parameterized tests.
  • When organizing tests by feature, using packages and @Nested for readability.
  • When you want controlled test order and lifecycle with @TestMethodOrder and static @BeforeAll/@AfterAll.
  • When writing tests that rely on mocks or isolated dependencies using Mockito.

Quick Start

  1. Step 1: Add junit-jupiter-api, junit-jupiter-engine, and junit-jupiter-params to your build (pom.xml or build.gradle).
  2. Step 2: Create tests under src/test/java, annotate with @Test or @ParameterizedTest, and apply AAA with @BeforeEach/@AfterEach or @BeforeAll/@AfterAll as needed.
  3. Step 3: Run mvn test or gradle test to execute the suite.

Best Practices

  • Keep tests focused on a single behavior.
  • Follow Arrange-Act-Assert and use descriptive test names, e.g., methodName_should_expectedBehavior_when_scenario.
  • Use per-test setup (@BeforeEach) and per-class setup (@BeforeAll) as appropriate.
  • Leverage parameterized tests with @ParameterizedTest and sources like @ValueSource, @MethodSource, @CsvSource, @CsvFileSource, and @EnumSource.
  • Group related assertions with assertAll and provide descriptive messages; consider using fluent assertions (AssertJ) when helpful.

Example Use Cases

  • CalculatorTest validates that add() returns the correct sum.
  • DataParserTest uses @ParameterizedTest with @ValueSource to cover multiple inputs.
  • UserServiceTest mocks UserRepository to verify login and save flows.
  • ConfigLoaderTest uses @EnumSource to test enum-driven paths.
  • FileProcessorTest employs @CsvSource to validate multiple conversion scenarios.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers