java-junit
Skill4 starsChanged 40 days agoMITView on GitHub
Best practices for JUnit 5 unit testing, including data-driven tests and modern patterns. Trigger: When writing JUnit tests, creating unit tests, or need testing best practices.
4 other projects use a version of this, 3 of them edited.
Adopted by
Most recently taken up by
- xpppppppppp/agent-skillsedited, first seen Nov 1, 2026
- github/awesome-copilottheir own version, first seen Oct 25, 2026
- PracticalSwan/agent-skillsedited, first seen Oct 19, 2026
- LucasMatuszewski/claude-code-course-jsystems-2026-07edited, first seen Jul 10, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 3
- PracticalSwan/agent-skills★ 2244% same
- LucasMatuszewski/claude-code-course-jsystems-2026-07★ 088% same
- xpppppppppp/agent-skills★ 088% same
Wrote their own version · 1
- github/awesome-copilot★ 41ksame name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- api-designSkill
- changelog-maintenanceSkill
- code-mentorSkill
- create-readmeSkill
- database-designSkill
- dockerSkill
- frontend-design-anti-slopSkill
- frontend-engineeringSkill
- git-commitSkill
- github-essentialsSkill
- java-springbootSkill
- java-springboot-testingSkill
- latexSkill
- solution-designSkill
- ui-componentsSkill
- update-readmeSkill
- vault-tech-noteSkill
- web-mvcSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
29 rules. 7 are common, 0 are distinctive, and 22 are very specific to this project.
7
Common
Most of the 4 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
22
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Common: line 23
Use a standard Maven or Gradle project structure
- Very specific: line 24
Place test source code in src/test/java
- Very specific: line 26
Use build tool commands to run tests: mvn test or gradle test
- Very specific: line 30
Test classes should have a Test suffix, e.g., CalculatorTest for a Calculator class
- Very specific: line 31
Use @Test for test methods
- Common: line 32
Follow the Arrange-Act-Assert (AAA) pattern
- Very specific: line 34
Use @BeforeEach and @AfterEach for per-test setup and teardown
- Very specific: line 35
Use @BeforeAll and @AfterAll for per-class setup and teardown (must be static methods)
- Very specific: line 36
Use @DisplayName to provide a human-readable name for test classes and methods
- Common: line 73
Keep tests focused on a single behavior
- Common: line 74
Avoid testing multiple conditions in one test method
- Very specific: line 80
Use @ParameterizedTest to mark a method as a parameterized test
- Very specific: line 81
Use @ValueSource for simple literal values (strings, ints, etc.)
- Very specific: line 82
Use @MethodSource to refer to a factory method that provides test arguments as a Stream, Collection, etc.
- Very specific: line 83
Use @CsvSource for inline comma-separated values
- Very specific: line 84
Use @CsvFileSource to use a CSV file from the classpath
- Very specific: line 85
Use @EnumSource to use enum constants
- Very specific: line 124
Use the static methods from org.junit.jupiter.api.Assertions (e.g., assertEquals, assertTrue, assertNotNull)
- Very specific: line 126
Use assertThrows or assertDoesNotThrow to test for exceptions
- Common: line 128
Use descriptive messages in assertions to provide clarity on failure
- Common: line 160
Use a mocking framework like Mockito to create mock objects for dependencies
- Very specific: line 161
Use @Mock and @InjectMocks annotations from Mockito to simplify mock creation and injection
- Common: line 162
Use interfaces to facilitate mocking
- Very specific: line 209
Use @Tag to categorize tests (e.g., @Tag("fast"), @Tag("integration"))
- Very specific: line 210
Use @TestMethodOrder(MethodOrderer.OrderAnnotation.class) and @Order to control test execution order when strictly necessary
- Very specific: line 211
Use @Disabled to temporarily skip a test method or class, providing a reason
- Very specific: line 212
Use @Nested to group tests in a nested inner class for better organization and structure
- Very specific: line 275
Resolve the libraryId: - Use context7_resolve-library-id:
- Very specific: line 279
Query the docs: - Use context7_query-docs:
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
When to Use
- Writing JUnit 5 unit tests
- Creating parameterized tests
- Setting up test infrastructure
- Need testing best practices for Java
Instructions
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, andjunit-jupiter-paramsfor parameterized tests - Use build tool commands to run tests:
mvn testorgradle test
Test Structure
- Test classes should have a
Testsuffix, e.g.,CalculatorTestfor aCalculatorclass - Use
@Testfor test methods - Follow the Arrange-Act-Assert (AAA) pattern
- Name tests using a descriptive convention, like
methodName_should_expectedBehavior_when_scenario - Use
@BeforeEachand@AfterEachfor per-test setup and teardown - Use
@BeforeAlland@AfterAllfor per-class setup and teardown (must be static methods) - Use
@DisplayNameto provide a human-readable name for test classes and methods
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
@DisplayName("Should add two positive numbers")
void add_shouldReturnSum_whenBothPositive() {
// Arrange
int a = 3, b = 5;
// Act
int result = calculator.add(a, b);
// Assert
assertEquals(8, result);
}
@Test
@DisplayName("Should throw exception when dividing by zero")
void divide_shouldThrowException_whenDenominatorIsZero() {
assertThrows(ArithmeticException.class,
() -> calculator.divide(10, 0),
"Division by zero should throw");
}
}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
@ParameterizedTestto mark a method as a parameterized test - Use
@ValueSourcefor simple literal values (strings, ints, etc.) - Use
@MethodSourceto refer to a factory method that provides test arguments as aStream,Collection, etc. - Use
@CsvSourcefor inline comma-separated values - Use
@CsvFileSourceto use a CSV file from the classpath - Use
@EnumSourceto use enum constants
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 5, 8, 13})
@DisplayName("Should identify Fibonacci numbers")
void isFibonacci_shouldReturnTrue_forFibonacciNumbers(int number) {
assertTrue(calculator.isFibonacci(number));
}
@ParameterizedTest
@CsvSource({
"4, 2, 2",
"10, 3, 1",
"7, 5, 2"
})
@DisplayName("Should compute modulo for various inputs")
void modulo_shouldReturnRemainder(int dividend, int divisor, int expected) {
assertEquals(expected, calculator.modulo(dividend, divisor));
}
@ParameterizedTest
@MethodSource("provideOrderStatuses")
@DisplayName("Should return correct display name for each status")
void getDisplayName_shouldReturnCorrectLabel(OrderStatus status, String expected) {
assertEquals(expected, status.getDisplayName());
}
static Stream<Arguments> provideOrderStatuses() {
return Stream.of(
Arguments.of(OrderStatus.PENDING, "Pending"),
Arguments.of(OrderStatus.SHIPPED, "Shipped"),
Arguments.of(OrderStatus.DELIVERED, "Delivered")
);
}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
assertThrowsorassertDoesNotThrowto test for exceptions - Group related assertions with
assertAllto ensure all assertions are checked before the test fails - Use descriptive messages in assertions to provide clarity on failure
@Test
@DisplayName("Should create order with all required fields")
void createOrder_shouldSetAllFields() {
Order order = orderService.create("customer-1", List.of("item-a"), 2990);
assertAll("order fields",
() -> assertEquals("customer-1", order.getCustomerId(), "customer id"),
() -> assertEquals(2, order.getItemCount(), "item count"),
() -> assertNotNull(order.getCreatedAt(), "creation timestamp"),
() -> assertEquals(OrderStatus.PENDING, order.getStatus(), "initial status")
);
}
// AssertJ example
@Test
@DisplayName("Should return orders sorted by date")
void findRecentOrders_shouldReturnSortedResults() {
List<Order> orders = orderService.findRecent(7);
assertThat(orders)
.isNotEmpty()
.hasSizeLessThanOrEqualTo(50)
.extracting(Order::getStatus)
.contains(OrderStatus.SHIPPED);
}Mocking and Isolation
- Use a mocking framework like Mockito to create mock objects for dependencies
- Use
@Mockand@InjectMocksannotations from Mockito to simplify mock creation and injection - Use interfaces to facilitate mocking
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock
private PaymentGateway paymentGateway;
@Mock
private InventoryClient inventoryClient;
@InjectMocks
private OrderService orderService;
@Test
@DisplayName("Should process payment when placing order")
void placeOrder_shouldProcessPayment() {
// Arrange
when(inventoryClient.isAvailable("item-1")).thenReturn(true);
when(paymentGateway.charge(any(Payment.class)))
.thenReturn(new PaymentResult("tx-123", PaymentStatus.SUCCESS));
// Act
Order order = orderService.placeOrder("customer-1", "item-1");
// Assert
assertThat(order.getTransactionId()).isEqualTo("tx-123");
verify(paymentGateway).charge(any(Payment.class));
}
@Test
@DisplayName("Should throw when inventory is insufficient")
void placeOrder_shouldThrow_whenItemUnavailable() {
when(inventoryClient.isAvailable("item-1")).thenReturn(false);
assertThrows(InsufficientInventoryException.class,
() -> orderService.placeOrder("customer-1", "item-1"));
verify(paymentGateway, never()).charge(any());
}
}Test Organization
- Group tests by feature or component using packages
- Use
@Tagto categorize tests (e.g.,@Tag("fast"),@Tag("integration")) - Use
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)and@Orderto control test execution order when strictly necessary - Use
@Disabledto temporarily skip a test method or class, providing a reason - Use
@Nestedto group tests in a nested inner class for better organization and structure
@DisplayName("OrderService")
class OrderServiceTest {
@Nested
@DisplayName("placeOrder")
class PlaceOrder {
@Test
@DisplayName("Should create order successfully")
void shouldCreateOrder() { }
@Test
@DisplayName("Should reject duplicate orders")
void shouldRejectDuplicate() { }
}
@Nested
@DisplayName("cancelOrder")
class CancelOrder {
@Test
@DisplayName("Should cancel pending order")
void shouldCancelPending() { }
@Test
@DisplayName("Should throw when order is already shipped")
void shouldThrowWhenShipped() { }
}
}Commands
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=CalculatorTest
# Run tests with specific tag
mvn test -Dgroups=fast
# Run tests with Gradle
gradle test
# Run specific test with Gradle
gradle test --tests CalculatorTestResources
Context7 Integration
For up-to-date information on JUnit 5 and AssertJ:
- Resolve the libraryId - Use
context7_resolve-library-id:libraryName: "junit 5", "assertj", or "mockito"query: what you need (e.g., "parameterized tests", "assertions")
- Query the docs - Use
context7_query-docs:libraryId: "/junit/junit5" or "/assertj/assertj"query: your specific question
Before writing tests, consult Context7 to get updated examples.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

