$npx -y skills add github/awesome-copilot --skill java-junitGet best practices for JUnit 5 unit testing, including data-driven tests
| 1 | # JUnit 5+ Best Practices |
| 2 | |
| 3 | Your goal is to help me write effective unit tests with JUnit 5, covering both standard and data-driven testing approaches. |
| 4 | |
| 5 | ## Project Setup |
| 6 | |
| 7 | - Use a standard Maven or Gradle project structure. |
| 8 | - Place test source code in `src/test/java`. |
| 9 | - Include dependencies for `junit-jupiter-api`, `junit-jupiter-engine`, and `junit-jupiter-params` for parameterized tests. |
| 10 | - Use build tool commands to run tests: `mvn test` or `gradle test`. |
| 11 | |
| 12 | ## Test Structure |
| 13 | |
| 14 | - Test classes should have a `Test` suffix, e.g., `CalculatorTest` for a `Calculator` class. |
| 15 | - Use `@Test` for test methods. |
| 16 | - Follow the Arrange-Act-Assert (AAA) pattern. |
| 17 | - Name tests using a descriptive convention, like `methodName_should_expectedBehavior_when_scenario`. |
| 18 | - Use `@BeforeEach` and `@AfterEach` for per-test setup and teardown. |
| 19 | - Use `@BeforeAll` and `@AfterAll` for per-class setup and teardown (must be static methods). |
| 20 | - Use `@DisplayName` to provide a human-readable name for test classes and methods. |
| 21 | |
| 22 | ## Standard Tests |
| 23 | |
| 24 | - Keep tests focused on a single behavior. |
| 25 | - Avoid testing multiple conditions in one test method. |
| 26 | - Make tests independent and idempotent (can run in any order). |
| 27 | - Avoid test interdependencies. |
| 28 | |
| 29 | ## Data-Driven (Parameterized) Tests |
| 30 | |
| 31 | - Use `@ParameterizedTest` to mark a method as a parameterized test. |
| 32 | - Use `@ValueSource` for simple literal values (strings, ints, etc.). |
| 33 | - Use `@MethodSource` to refer to a factory method that provides test arguments as a `Stream`, `Collection`, etc. |
| 34 | - Use `@CsvSource` for inline comma-separated values. |
| 35 | - Use `@CsvFileSource` to use a CSV file from the classpath. |
| 36 | - Use `@EnumSource` to use enum constants. |
| 37 | |
| 38 | ## Assertions |
| 39 | |
| 40 | - Use the static methods from `org.junit.jupiter.api.Assertions` (e.g., `assertEquals`, `assertTrue`, `assertNotNull`). |
| 41 | - For more fluent and readable assertions, consider using a library like AssertJ (`assertThat(...).is...`). |
| 42 | - Use `assertThrows` or `assertDoesNotThrow` to test for exceptions. |
| 43 | - Group related assertions with `assertAll` to ensure all assertions are checked before the test fails. |
| 44 | - Use descriptive messages in assertions to provide clarity on failure. |
| 45 | |
| 46 | ## Mocking and Isolation |
| 47 | |
| 48 | - Use a mocking framework like Mockito to create mock objects for dependencies. |
| 49 | - Use `@Mock` and `@InjectMocks` annotations from Mockito to simplify mock creation and injection. |
| 50 | - Use interfaces to facilitate mocking. |
| 51 | |
| 52 | ## Test Organization |
| 53 | |
| 54 | - Group tests by feature or component using packages. |
| 55 | - Use `@Tag` to categorize tests (e.g., `@Tag("fast")`, `@Tag("integration")`). |
| 56 | - Use `@TestMethodOrder(MethodOrderer.OrderAnnotation.class)` and `@Order` to control test execution order when strictly necessary. |
| 57 | - Use `@Disabled` to temporarily skip a test method or class, providing a reason. |
| 58 | - Use `@Nested` to group tests in a nested inner class for better organization and structure. |