Middle
What types of tests do you write and how?
sobes.tech AI
Answer from AI
I write the following types of tests:
- Unit tests: Test individual components (classes, methods) in isolation. I use JUnit or TestNG, mocks with Mockito.
- Integration tests: Check interaction between multiple components or subsystems (e.g., service with database). I often use Spring Boot Test and Testcontainers.
- Component tests: Cover functionality of a specific component of the system as a whole, including its interaction with external dependencies (often mocked).
- End-to-End (E2E) tests: Test the complete operation of the entire system from start to finish, simulating user actions. They may use Selenium, Cypress (for web).
Test writing process:
- Understanding requirements: Clearly define what the code under test should do.
- Choosing test type: Determine which type of test is most suitable for the functionality (Unit, Integration, etc.).
- Setting up test environment: Prepare necessary dependencies, mocks, test data.
- Writing test scenario: Define sequence of actions and expected result.
- Writing test code: Implement the test scenario using the chosen framework.
- Running the test: Execute the test and ensure it passes successfully.
- Refactoring the test: Improve readability and maintainability if needed.
Example of a Unit test with Mockito:
// Imports omitted for brevity
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testGetUserById_Success() {
// Prepare data
long userId = 1L;
User mockUser = new User(userId, "testuser");
when(userRepository.findById(userId)).thenReturn(Optional.of(mockUser));
// Execute the method under test
Optional<User> result = userService.getUserById(userId);
// Verify the result
assertTrue(result.isPresent());
assertEquals("testuser", result.get().getUsername());
verify(userRepository, times(1)).findById(userId); // Verify repository method was called once
}
@Test
void testGetUserById_NotFound() {
// Prepare data
long userId = 2L;
when(userRepository.findById(userId)).thenReturn(Optional.empty());
// Execute the method under test
Optional<User> result = userService.getUserById(userId);
// Verify the result
assertFalse(result.isPresent());
verify(userRepository, times(1)).findById(userId);
}
}
Example of an Integration test with Spring Boot Test and Testcontainers:
// Imports omitted for brevity
@SpringBootTest
@Testcontainers
public class UserRepositoryIntegrationTest {
@Container
private static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:13")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@Autowired
private UserRepository userRepository;
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgresContainer::getJdbcUrl);
registry.add("spring.datasource.username", postgresContainer::getUsername);
registry.add("spring.datasource.password", postgresContainer::getPassword);
}
@Test
void testSaveAndFindUser() {
// Create test user
User newUser = new User(null, "integration_user");
// Save user
User savedUser = userRepository.save(newUser);
assertNotNull(savedUser.getId());
// Find user
Optional<User> foundUserOptional = userRepository.findById(savedUser.getId());
assertTrue(foundUserOptional.isPresent());
User foundUser = foundUserOptional.get();
assertEquals("integration_user", foundUser.getUsername());
}
}