
Spring Boot Testing
Write readable Spring Boot unit and integration tests using AssertJ fluent assertions and JUnit 5 patterns.
Overview
Spring Boot Testing is an agent skill for the Ship phase that helps you write fluent AssertJ assertions and JUnit 5 tests for Spring Boot Java code.
Install
npx skills add https://github.com/github/awesome-copilot --skill spring-boot-testingWhat is this skill?
- AssertJ fluent assertions for objects, strings, numbers, and booleans
- Date/time, Optional, and exception assertion patterns
- JUnit 5-friendly examples for service-layer tests
- Readable maintainable test style for Spring Boot domain models
- Copy-paste assertion recipes for common order and entity scenarios
Adoption & trust: 1.5k installs on skills.sh; 34.6k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Spring Boot tests are hard to read and debug because assertions are scattered JUnit checks without fluent intent.
Who is it for?
Indie Java developers shipping Spring Boot APIs who want AssertJ-first unit tests.
Skip if: Non-JVM stacks, frontend-only test suites, or full load-test and chaos engineering programs.
When should I use this skill?
User is writing or improving Spring Boot Java tests and needs AssertJ assertion patterns or JUnit 5 exception test examples.
What do I get? / Deliverables
You apply consistent AssertJ patterns for strings, numbers, dates, Optionals, and exceptions so test failures pinpoint behavior quickly.
- Test methods using AssertJ fluent assertions
- Exception and Optional assertion blocks ready to adapt
Recommended Skills
Journey fit
How it compares
Assertion and JUnit recipe reference—not a replacement for Spring Boot Testcontainers or contract-test infrastructure.
Common Questions / FAQ
Who is spring-boot-testing for?
Solo builders and small teams on Spring Boot who already write JUnit tests and want AssertJ fluency for clearer failures.
When should I use spring-boot-testing?
During Ship and testing when adding or refactoring unit tests for services, entities, and exception paths before merge or release.
Is spring-boot-testing safe to install?
It is documentation-style testing guidance without inherent network access; still review the Security Audits panel on this Prism page for the upstream package.
SKILL.md
READMESKILL.md - Spring Boot Testing
# AssertJ Basics Fluent assertions for readable, maintainable tests. ## Basic Assertions ### Object Equality ```java assertThat(order.getStatus()).isEqualTo("PENDING"); assertThat(order.getId()).isNotEqualTo(0); assertThat(order).isEqualTo(expectedOrder); assertThat(order).isNotNull(); assertThat(nullOrder).isNull(); ``` ### String Assertions ```java assertThat(order.getDescription()) .isEqualTo("Test Order") .startsWith("Test") .endsWith("Order") .contains("Test") .hasSize(10) .matches("[A-Za-z ]+"); ``` ### Number Assertions ```java assertThat(order.getAmount()) .isEqualTo(99.99) .isGreaterThan(50) .isLessThan(100) .isBetween(50, 100) .isPositive() .isNotZero(); ``` ### Boolean Assertions ```java assertThat(order.isActive()).isTrue(); assertThat(order.isDeleted()).isFalse(); ``` ## Date/Time Assertions ```java assertThat(order.getCreatedAt()) .isEqualTo(LocalDateTime.of(2024, 1, 15, 10, 30)) .isBefore(LocalDateTime.now()) .isAfter(LocalDateTime.of(2024, 1, 1)) .isCloseTo(LocalDateTime.now(), within(5, ChronoUnit.SECONDS)); ``` ## Optional Assertions ```java Optional<Order> maybeOrder = orderService.findById(1L); assertThat(maybeOrder) .isPresent() .hasValueSatisfying(order -> { assertThat(order.getId()).isEqualTo(1L); }); assertThat(orderService.findById(999L)).isEmpty(); ``` ## Exception Assertions ### JUnit 5 Exception Handling ```java @Test void shouldThrowException() { OrderService service = new OrderService(); assertThatThrownBy(() -> service.findById(999L)) .isInstanceOf(OrderNotFoundException.class) .hasMessage("Order 999 not found") .hasMessageContaining("999"); } ``` ### AssertJ Exception Handling ```java @Test void shouldThrowExceptionWithCause() { assertThatExceptionOfType(OrderProcessingException.class) .isThrownBy(() -> service.processOrder(invalidOrder)) .withCauseInstanceOf(ValidationException.class); } ``` ## Custom Assertions Create domain-specific assertions for reusable test code: ```java public class OrderAssert extends AbstractAssert<OrderAssert, Order> { public static OrderAssert assertThat(Order actual) { return new OrderAssert(actual); } private OrderAssert(Order actual) { super(actual, OrderAssert.class); } public OrderAssert isPending() { isNotNull(); if (!"PENDING".equals(actual.getStatus())) { failWithMessage("Expected order status to be PENDING but was %s", actual.getStatus()); } return this; } public OrderAssert hasTotal(BigDecimal expected) { isNotNull(); if (!expected.equals(actual.getTotal())) { failWithMessage("Expected total %s but was %s", expected, actual.getTotal()); } return this; } } ``` Usage: ```java OrderAssert.assertThat(order) .isPending() .hasTotal(new BigDecimal("99.99")); ``` ## Soft Assertions Collect multiple failures before failing: ```java @Test void shouldValidateOrder() { Order order = orderService.findById(1L); SoftAssertions.assertSoftly(softly -> { softly.assertThat(order.getId()).isEqualTo(1L); softly.assertThat(order.getStatus()).isEqualTo("PENDING"); softly.assertThat(order.getItems()).isNotEmpty(); }); } ``` ## Satisfies Pattern ```java assertThat(order) .satisfies(o -> { assertThat(o.getId()).isPositive(); assertThat(o.getStatus()).isNotBlank(); assertThat(o.getCreatedAt()).isNotNull(); }); ``` ## Using with Spring ```java import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest class OrderServiceTest { @Autowired private OrderService orderService; @Test void shouldCreateOrder() { Order order = orderService.create(new OrderRequest("Product", 2)); assertThat(order) .isNotNull() .extracting(Order::getId, Order::getStatus) .containsExactly(1L, "PENDING"); } } ``` ## Static Import Always use static import for clean assertions: ```java import static org.assertj.core.api.Assertions.