Integration testing is a level of software testing where individual components are combined and tested as a group. The purpose is to expose faults in the interaction between integrated components. This type of testing focuses on verifying that different parts of the application work together correctly.
All components are integrated at once and tested as a whole.
Components are integrated and tested one at a time.
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserRepository userRepository;
@Test
void createUser_ValidData_ReturnsCreatedUser() throws Exception {
// Given
UserDTO userDTO = new UserDTO("john@example.com", "password123");
// When/Then
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(userDTO)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.email").value("john@example.com"));
}
}
@DataJpaTest
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
void findByEmail_ExistingUser_ReturnsUser() {
// Given
User user = new User("john@example.com", "password123");
userRepository.save(user);
// When
Optional found = userRepository.findByEmail("john@example.com");
// Then
assertTrue(found.isPresent());
assertEquals("john@example.com", found.get().getEmail());
}
}
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class UserApiIntegrationTest {
@BeforeEach
void setup() {
RestAssured.baseURI = "http://localhost:8080";
}
@Test
void getUser_ExistingUser_ReturnsUser() {
given()
.when()
.get("/api/users/1")
.then()
.statusCode(200)
.body("email", equalTo("john@example.com"))
.body("name", equalTo("John Doe"));
}
}
@Test
void createUser_InvalidData_ReturnsBadRequest() throws Exception {
// Given
UserDTO invalidUser = new UserDTO("invalid-email", "");
// When/Then
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(invalidUser)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors").isArray())
.andExpect(jsonPath("$.errors[0].field").value("email"));
}
@SpringBootTest
@Testcontainers
public class DatabaseIntegrationTest {
@Container
static PostgreSQLContainer> postgres = new PostgreSQLContainer<>("postgres:13");
@DynamicPropertySource
static void postgresProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Test
void testDatabaseConnection() {
assertTrue(postgres.isRunning());
}
}
@BeforeEach
void setupTestData() {
// Clear existing data
userRepository.deleteAll();
// Create test data
User user1 = new User("user1@example.com", "password123");
User user2 = new User("user2@example.com", "password456");
userRepository.saveAll(Arrays.asList(user1, user2));
}