Тестирование Java с нуля: дорожная карта для новичка

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

«Код без тестов — это legacy»: почему вам стоит начать уже сегодня

Представьте: вы написали приложение на Java. Оно работает. Но вы боитесь что-то менять, потому что одно неверное движение — и всё рухнет. Знакомо? Добро пожаловать в мир, где тестирование Java — не прихоть, а навык выживания.

Многие начинающие разработчики откладывают тесты «на потом». Мол, сначала научусь писать код, а потом разберусь. Но правда в том, что юнит-тесты Java — это не дополнительная нагрузка, а ваш страховочный трос. Они заставляют вас писать более качественный, модульный и понятный код. И да, работодатели очень ценят разработчиков, которые умеют покрывать код тестами.

В этой статье мы разберем, с чего начать тестирование Java новичку. Вы узнаете про основные инструменты — JUnit и Mockito, напишете свои первые тесты и поймете, как не скатиться в «тестирование ради тестирования». Поехали!

Шаг 1: Настройка окружения — ваш первый тестовый стенд

Прежде чем писать тесты, нужно подготовить среду. Хорошая новость: для автоматизации тестирования Java вам не нужно ничего сверхъестественного. Всё, что у вас уже есть, — это JDK и IDE (IntelliJ IDEA или Eclipse).

Maven или Gradle — выбираем сборщик

Современные Java-проекты редко обходятся без системы сборки. Мы будем использовать Maven — он де-факто стандарт для большинства проектов. Вот минимальный pom.xml с зависимостями для тестирования:

<dependencies>
    <!-- JUnit 5 — основной фреймворк для тестов -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
    
    <!-- Mockito для создания mock-объектов -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>5.6.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Обратите внимание на <scope>test</scope> — эти библиотеки не попадут в финальную сборку приложения, они нужны только для запуска тестов.

Шаг 2: JUnit — ваш первый настоящий тест

JUnit — это фундамент, на котором строится всё тестирование Java. С его помощью вы пишете юнит-тесты: проверяете работу одного метода или класса в изоляции.

Пишем первый тест

Допустим, у нас есть простой калькулятор:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public int divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Делить на ноль нельзя!");
        }
        return a / b;
    }
}

Теперь напишем тест для него. Создайте класс в папке src/test/java:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {
    
    private final Calculator calculator = new Calculator();
    
    @Test
    void testAdd() {
        // Arrange (подготовка)
        int a = 2;
        int b = 3;
        
        // Act (действие)
        int result = calculator.add(a, b);
        
        // Assert (проверка)
        assertEquals(5, result, "2 + 3 должно быть равно 5");
    }
    
    @Test
    void testDivideByZero() {
        // Проверяем, что метод выбрасывает исключение
        assertThrows(IllegalArgumentException.class, 
            () -> calculator.divide(10, 0));
    }
}

Запустите тест — зеленая полоска в IDE скажет вам, что всё работает. Поздравляю, вы только что сделали первый шаг в unit testing Java!

Паттерн AAA: Arrange-Act-Assert

Обратите внимание на структуру теста. Это не случайность. Лучшие практики тестирования Java рекомендуют придерживаться паттерна AAA:

  • Arrange — подготовка данных и объектов
  • Act — выполнение тестируемого действия
  • Assert — проверка результата

Это делает тесты читаемыми и понятными даже для тех, кто видит их впервые.

Шаг 3: Mockito — когда тестировать нечего, но очень хочется

В реальных проектах классы редко существуют сами по себе. Они общаются с базой данных, вызывают внешние API, работают с файловой системой. Как протестировать такой код, не поднимая настоящую базу?

На помощь приходит Mockito — библиотека для создания mock-объектов (заглушек).

Пример: тестируем сервис с зависимостью

Представьте сервис, который сохраняет пользователя и отправляет ему email:

public class UserService {
    private final UserRepository repository;
    private final EmailService emailService;
    
    public UserService(UserRepository repository, EmailService emailService) {
        this.repository = repository;
        this.emailService = emailService;
    }
    
    public User registerUser(String name, String email) {
        User user = new User(name, email);
        repository.save(user);                // сохраняем в БД
        emailService.sendWelcomeEmail(user);  // отправляем письмо
        return user;
    }
}

Чтобы протестировать этот метод, нам нужно проверить, что:

  • repository.save() был вызван с правильным пользователем
  • emailService.sendWelcomeEmail() был вызван один раз

Вот как это делается с Mockito:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class) // Включаем поддержку Mockito в JUnit 5
class UserServiceTest {
    
    @Mock
    private UserRepository repository;
    
    @Mock
    private EmailService emailService;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    void testRegisterUser() {
        // Arrange
        String name = "Иван";
        String email = "ivan@example.com";
        
        // Act
        User result = userService.registerUser(name, email);
        
        // Assert
        assertEquals(name, result.getName());
        assertEquals(email, result.getEmail());
        
        // Проверяем, что методы были вызваны
        verify(repository).save(any(User.class));
        verify(emailService, times(1)).sendWelcomeEmail(any(User.class));
    }
}

Обратите внимание на аннотации: @Mock создает заглушку, а @InjectMocks автоматически внедряет эти заглушки в тестируемый объект. Mock-объекты Java позволяют изолировать тестируемый

Блоги

Рекомендаций по книгам