Java Testing Standards
Intermediate
Write effective Java tests with JUnit 5 — descriptive test names, AAA pattern, proper mocking with Mockito, test isolation, and meaningful assertions over trivial checks.
File Patterns
**/*Test.java**/*Tests.java**/*Spec.java**/pom.xml
This rule applies to files matching the patterns above.
Rule Content
rule-content.md
# Java Testing Standards
## Rule
All Java projects MUST use JUnit 5 with Mockito. Tests MUST follow the Arrange-Act-Assert pattern, use descriptive names, and achieve minimum 80% line coverage on business logic.
## Format
```java
@DisplayName("OrderService")
class OrderServiceTest {
@Test
@DisplayName("should create order with valid items")
void shouldCreateOrderWithValidItems() {
// Arrange
// Act
// Assert
}
}
```
## Good Examples
```java
@ExtendWith(MockitoExtension.class)
@DisplayName("OrderService")
class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@Mock
private PaymentGateway paymentGateway;
@InjectMocks
private OrderService orderService;
@Test
@DisplayName("should create order when items are valid")
void shouldCreateOrderWhenItemsAreValid() {
// Arrange
var request = new CreateOrderRequest(List.of(
new OrderItem("SKU-001", 2, BigDecimal.valueOf(29.99))
));
var expectedOrder = Order.from(request);
when(orderRepository.save(any(Order.class))).thenReturn(expectedOrder);
// Act
var result = orderService.createOrder(request);
// Assert
assertThat(result).isNotNull();
assertThat(result.items()).hasSize(1);
verify(orderRepository).save(any(Order.class));
}
@Test
@DisplayName("should throw when order has no items")
void shouldThrowWhenOrderHasNoItems() {
var request = new CreateOrderRequest(List.of());
assertThatThrownBy(() -> orderService.createOrder(request))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Order must have at least one item");
verify(orderRepository, never()).save(any());
}
}
```
## Bad Examples
```java
// BAD: Meaningless test name
@Test
void test1() { ... }
// BAD: No assertion — test always passes
@Test
void testCreateOrder() {
orderService.createOrder(request);
// No assert — just checking it doesn't throw
}
// BAD: Testing implementation, not behavior
@Test
void testCreateOrderCallsRepositorySaveThenCallsPaymentThenCallsNotification() {
// Overly specific verification — brittle test
}
```
## Enforcement
- JaCoCo coverage threshold in build: 80% minimum
- CI fails on test failures — no `-DskipTests`
- Use @DisplayName for human-readable test reportsFAQ
Discussion
Loading comments...