Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие библиотеки для тестов использовал
Testing является критичной частью разработки. Я работал с различными популярными библиотеками для Java.
Unit Testing Фреймворки
1. JUnit — основной фреймворк
@DisplayName("Calculator Tests")
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
@DisplayName("2 + 2 should equal 4")
void testAddition() {
assertEquals(4, calculator.add(2, 2));
}
@Test
@DisplayName("Should throw exception for division by zero")
void testDivisionByZero() {
assertThrows(ArithmeticException.class, () -> calculator.divide(10, 0));
}
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 5, 7})
void testOddNumbers(int number) {
assertTrue(number % 2 != 0);
}
}
Mocking Фреймворки
2. Mockito — главный выбор для mock'ов
class OrderServiceTest {
@Mock
private PaymentService paymentService;
@InjectMocks
private OrderService orderService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testOrderCreation() {
// Arrange
Order order = new Order(1L, BigDecimal.valueOf(100));
when(paymentService.processPayment(any()))
.thenReturn(true);
// Act
boolean result = orderService.createOrder(order);
// Assert
assertTrue(result);
verify(paymentService, times(1)).processPayment(any());
}
}
3. WireMock — для mock'ирования HTTP запросов
@ExtendWith(WireMockExtension.class)
class PaymentApiClientTest {
private PaymentApiClient client;
@BeforeEach
void setUp(WireMockRuntimeInfo wmRuntimeInfo) {
client = new PaymentApiClient(wmRuntimeInfo.getHttpBaseUrl());
}
@Test
void testPaymentProcessing(WireMockRuntimeInfo wmRuntimeInfo) {
// Mock HTTP endpoint
wmRuntimeInfo.getWireMock().register(
post(urlEqualTo("/api/payments"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"transactionId\": \"123\"}"))
);
Payment result = client.processPayment(100.0);
assertEquals("123", result.getTransactionId());
}
}
Assertion Фреймворки
4. AssertJ — fluent assertions (предпочитаю)
class UserTest {
@Test
void testUserValidation() {
User user = new User("john@example.com", "John", 30);
assertThat(user)
.isNotNull()
.hasFieldOrPropertyWithValue("email", "john@example.com")
.hasFieldOrPropertyWithValue("age", 30);
List<User> users = List.of(user);
assertThat(users)
.isNotEmpty()
.hasSize(1)
.allMatch(u -> u.getAge() >= 18);
}
}
Integration Testing
5. Spring Boot Test — для интеграционных тестов
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void testGetUser() throws Exception {
User user = new User(1L, "john@example.com", "John");
when(userService.getUserById(1L)).thenReturn(user);
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.email").value("john@example.com"))
.andExpect(jsonPath("$.name").value("John"));
}
}
// Тестирование JPA repositories
@DataJpaTest
class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository userRepository;
@Test
void testFindByEmail() {
User user = new User("john@example.com", "John");
entityManager.persistAndFlush(user);
User found = userRepository.findByEmail("john@example.com");
assertThat(found).isNotNull();
assertThat(found.getName()).isEqualTo("John");
}
}
Performance Testing
6. JMH — для бенчмарков
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class ListPerformanceBenchmark {
private List<Integer> arrayList;
private List<Integer> linkedList;
@Setup
public void setup() {
arrayList = new ArrayList<>();
linkedList = new LinkedList<>();
for (int i = 0; i < 10000; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public int arrayListIteration() {
int sum = 0;
for (Integer value : arrayList) {
sum += value;
}
return sum;
}
}
Contract Testing
7. Pact — для contract testing
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "UserProvider", port = "8080")
class UserServiceConsumerTest {
@Pact(provider = "UserProvider", consumer = "UserConsumer")
public RequestResponsePact createPact(PactBuilder builder) {
return builder
.given("user exists")
.uponReceiving("a request for user 1")
.path("/api/users/1")
.method("GET")
.willRespondWith()
.status(200)
.body(eachLike(
new PactDslJsonBody()
.stringValue("email", "john@example.com")
.stringValue("name", "John")
))
.toPact();
}
}
E2E Testing
8. Playwright (MCP) — для E2E тестирования
class UserInterfaceE2ETest {
@Test
void testUserRegistration() {
// Открыть страницу
browser.navigate("http://localhost:3000/register");
// Заполнить форму
page.fill("input[name='email']", "new@example.com");
page.fill("input[name='password']", "securePassword123");
page.fill("input[name='confirmPassword']", "securePassword123");
// Отправить
page.click("button:has-text('Register')");
// Проверить результат
assertThat(page.locator("h1")).containsText("Welcome");
}
}
Coverage Tools
9. JaCoCo — для code coverage
<!-- pom.xml -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Мой стек для типичного проекта
Unit Tests: JUnit 5 + Mockito + AssertJ
Integration: Spring Boot Test + @DataJpaTest
HTTP Mocking: WireMock
Performance: JMH
Contract Testing: Pact
E2E Testing: Playwright (MCP)
Coverage: JaCoCo
Load Testing: Gatling (если нужно)
Best Practices
- Unit tests должны быть быстрыми (< 1 мс)
- Integration tests отдельно от unit tests
- Mock external dependencies (API, БД, сервисы)
- Test coverage минимум 80-90%
- Given-When-Then структура тестов
- Параметризованные тесты для граничных условий
- Не тестируй гетеры/сеттеры (очевидно работают)
- One assertion per test или все связанные вместе