Lançado · em melhoria
Guia de Spring Boot · 5/6
Por enquanto, este capítulo está disponível apenas em inglês.
Spring Boot bundles JUnit Jupiter, AssertJ, Mockito and Spring Test, and supports both slice tests, which start only part of the application, and integration tests, which start all of it. This chapter goes from the fastest kind of test to the slowest.
Projects generated by Initializr include a test starter per technology (spring-boot-starter-webmvc-test, spring-boot-starter-data-jpa-test and so on). Run tests through the build tool:
./gradlew test
./mvnw test
# Run a single test class
./gradlew test --tests "com.example.demo.todo.TodoServiceTests"With constructor injection you can create objects by hand and test them without Spring at all. These tests are the fastest, so use them for business rules.
class GreetingServiceTests {
@Test
void greetsInTheMorning() {
Clock morning = Clock.fixed(Instant.parse("2025-01-01T08:00:00Z"), ZoneOffset.UTC);
GreetingService service = new GreetingService(morning);
assertThat(service.greet("Kim")).isEqualTo("Good morning, Kim");
}
}@WebMvcTest starts only the MVC infrastructure (controllers, JSON conversion, validation) and registers no services or repositories. Replace the beans a controller depends on with mocks via @MockitoBean. MockMvcTester lets you assert on requests and responses in AssertJ style.
@WebMvcTest(TodoController.class)
class TodoControllerTests {
@Autowired
MockMvcTester mvc;
@MockitoBean
TodoService service;
@Test
void returnsTodo() {
given(service.find(1L)).willReturn(new TodoResponse(1L, "Write docs", false));
assertThat(mvc.get().uri("/api/todos/1"))
.hasStatusOk()
.bodyJson().extractingPath("$.title").isEqualTo("Write docs");
}
@Test
void rejectsBlankTitle() {
assertThat(mvc.post().uri("/api/todos")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"title\": \"\"}"))
.hasStatus(HttpStatus.BAD_REQUEST);
}
}The previous generation used @MockBean; it has been replaced by Spring Framework's @MockitoBean.
@DataJpaTest configures only JPA-related beans and runs each test in a transaction that is rolled back afterwards. If an embedded database such as H2 is on the classpath, it is used in place of your configured one by default. To run the example below as is, add testRuntimeOnly("com.h2database:h2"), or use Testcontainers as shown later.
@DataJpaTest
class TodoRepositoryTests {
@Autowired
TestEntityManager entityManager;
@Autowired
TodoRepository repository;
@Test
void findsOpenTodos() {
entityManager.persist(new Todo("open"));
Todo done = new Todo("done");
done.complete();
entityManager.persist(done);
assertThat(repository.findByDoneFalseOrderByIdAsc())
.extracting(Todo::getTitle)
.containsExactly("open");
}
}@SpringBootTest starts the same context as the real application. Add @AutoConfigureMockMvc when you want MockMvc, or set webEnvironment = WebEnvironment.RANDOM_PORT to start a real server on a random port.
To test against the same database you run in production, use Testcontainers. It starts the database in Docker, and @ServiceConnection wires the connection details for you, so no spring.datasource.url is needed.
@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class TodoRepositoryPostgresTests {
@Container
@ServiceConnection
static PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:alpine");
@Autowired
TodoRepository repository;
@Test
void savesTodo() {
Todo saved = repository.save(new Todo("from container"));
assertThat(saved.getId()).isNotNull();
}
}replace = NONE tells Spring Boot to keep the container instead of swapping in an embedded database, and your Flyway migrations run against it too. When you pick testcontainers in Initializr, it also generates TestcontainersConfiguration and TestDemoApplication, so ./gradlew bootTestRun (or ./mvnw spring-boot:test-run) runs the app locally against a container database.
@WebMvcTest and @MockitoBean, and the data layer with @DataJpaTest.@SpringBootTest.@ServiceConnection.
0 comentários
Fazer login · Faça login para deixar um comentário.
Seja o primeiro a comentar.