← Назад к вопросам

Что такое unit в Unit-тестировании?

1.0 Junior🔥 211 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Unit-тестирование и понятие Unit

Unit (модуль) в unit-тестировании — это **наименьшая тестируемая часть приложения, которая может быть протестирована изолированно**. Обычно это одна функция, метод класса или небольшой компонент.

Что такое Unit?

Unit — это отдельная, логически завершённая часть кода, которая:

  • Имеет чёткую ответственность: выполняет одну задачу
  • Может быть протестирована независимо: без зависимостей от других модулей
  • Имеет входные данные (input): параметры метода
  • Имеет выходные данные (output): возвращаемое значение

Примеры Unit

// Unit 1: Вычисление скидки
public class DiscountCalculator {
    public double calculateDiscount(double originalPrice, int discountPercent) {
        // Один Unit — один метод
        return originalPrice * (1 - discountPercent / 100.0);
    }
}

// Unit 2: Валидация email
public class EmailValidator {
    public boolean isValidEmail(String email) {
        // Один Unit — проверка email
        return email != null && email.contains("@") && email.contains(".");
    }
}

// Unit 3: Поиск максимального значения
public class ArrayUtils {
    public int findMax(int[] arr) {
        // Один Unit — поиск максимума
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("Array is empty");
        }
        return java.util.Arrays.stream(arr).max().orElse(Integer.MIN_VALUE);
    }
}

Unit vs Integration тестирование

ХарактеристикаUnitIntegration
Область тестированияОдин метод/компонентНесколько компонентов вместе
Скорость выполненияОчень быстро (мс)Медленнее (сек)
ЗависимостиМокируютсяИспользуются реальные
СложностьПростоеСложнее
Частота запускаЧасто (CI/CD)Реже
Что тестируетЛогикуИнтеграцию компонентов

Unit-тестирование с JUnit

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

public class DiscountCalculatorTest {
    private DiscountCalculator calculator = new DiscountCalculator();
    
    @Test
    public void testCalculateDiscount_AppliesDiscount() {
        // Arrange (подготовка)
        double originalPrice = 100.0;
        int discountPercent = 20;
        
        // Act (выполнение)
        double result = calculator.calculateDiscount(originalPrice, discountPercent);
        
        // Assert (проверка)
        assertEquals(80.0, result);
    }
    
    @Test
    public void testCalculateDiscount_NoDiscount() {
        double result = calculator.calculateDiscount(100.0, 0);
        assertEquals(100.0, result);
    }
    
    @Test
    public void testCalculateDiscount_FullDiscount() {
        double result = calculator.calculateDiscount(100.0, 100);
        assertEquals(0.0, result);
    }
}

AAA паттерн (Arrange-Act-Assert)

Структура unit-теста:

@Test
public void testUserCreation() {
    // ARRANGE — подготовка данных и объектов
    String username = "john_doe";
    String email = "john@example.com";
    User user = new User();
    
    // ACT — выполнение тестируемого действия
    user.setUsername(username);
    user.setEmail(email);
    
    // ASSERT — проверка результатов
    assertEquals(username, user.getUsername());
    assertEquals(email, user.getEmail());
    assertNotNull(user);
}

Мокирование зависимостей

Unit — это изолированный модуль. Зависимости мокируются:

import org.mockito.Mock;
import org.mockito.InjectMocks;
import static org.mockito.Mockito.*;

public class UserServiceTest {
    @Mock
    private UserRepository userRepository; // Мокируем зависимость
    
    @InjectMocks
    private UserService userService; // Инжектим в сервис
    
    @Test
    public void testGetUserById() {
        // Arrange
        User expectedUser = new User(1L, "John Doe");
        when(userRepository.findById(1L)).thenReturn(expectedUser);
        
        // Act
        User result = userService.getUserById(1L);
        
        // Assert
        assertEquals("John Doe", result.getName());
        verify(userRepository, times(1)).findById(1L);
    }
}

Шаги для написания Unit-теста

1. Определи Unit (что тестировать):

public class PaymentProcessor {
    public boolean processPayment(double amount) {
        // Unit — обработка платежа
        return amount > 0;
    }
}

2. Напиши тест:

public class PaymentProcessorTest {
    private PaymentProcessor processor = new PaymentProcessor();
    
    @Test
    public void testProcessPayment_PositiveAmount_ReturnsTrue() {
        boolean result = processor.processPayment(100.0);
        assertTrue(result);
    }
    
    @Test
    public void testProcessPayment_NegativeAmount_ReturnsFalse() {
        boolean result = processor.processPayment(-50.0);
        assertFalse(result);
    }
    
    @Test
    public void testProcessPayment_ZeroAmount_ReturnsFalse() {
        boolean result = processor.processPayment(0.0);
        assertFalse(result);
    }
}

Хорошие Unit-тесты имеют свойства FIRST

F — Fast (быстрые): Выполняются за миллисекунды

// Быстро — вычисление в памяти
@Test
public void quickTest() {
    assertEquals(4, 2 + 2);
}

I — Independent (независимые): Не зависят друг от друга

// Каждый тест может запуститься отдельно
@Test
public void test1() { /* ... */ }

@Test
public void test2() { /* ... */ } // Не зависит от test1

R — Repeatable (повторяемые): Дают одинаковый результат каждый раз

// Одинаковый результат при множественных запусках
@Test
public void repeatableTest() {
    assertEquals(5, calculator.add(2, 3));
}

E — Explicit (явные): Ясно показывают, что тестируют

// Название явно описывает тест
@Test
public void testAddition_WithPositiveNumbers_ReturnsSum() {
    assertEquals(5, calculator.add(2, 3));
}

T — Timely (своевременные): Пишутся перед кодом (TDD) или с кодом

// Пишем тест в момент разработки

Примеры различных Unit-тестов

Тест исключений:

@Test
public void testDivisionByZero_ThrowsException() {
    assertThrows(ArithmeticException.class, () -> {
        calculator.divide(10, 0);
    });
}

Тест коллекций:

@Test
public void testAddToList_SizeIncreases() {
    List<String> list = new ArrayList<>();
    list.add("item");
    assertEquals(1, list.size());
    assertTrue(list.contains("item"));
}

Тест временных интервалов:

@Test
public void testOperationTimeout() {
    assertTimeout(java.time.Duration.ofSeconds(2), () -> {
        // Операция должна завершиться менее чем за 2 секунды
        complexOperation();
    });
}

Процентное содержание тестов

Обычное распределение:

  • 70-80% Unit тесты — быстрые, дешёвые, много
  • 10-20% Integration тесты — медленнее, дороже
  • 5-10% E2E тесты — самые медленные, самые дорогие

Заключение

Unit-тестирование — это фундамент качественного software. Unit — это минимальная, изолированная, логически завершённая часть кода, которая тестируется отдельно от остального приложения. Правильное unit-тестирование гарантирует стабильность и надёжность приложения.

Что такое unit в Unit-тестировании? | PrepBro