Ответ
Интеграционные тесты проверяют взаимодействие между несколькими компонентами системы (например, сервис и база данных). В Go для этого используются следующие подходы и инструменты:
1. Тестирование HTTP-слоя с net/http/httptest
Стандартная библиотека предоставляет пакет httptest
для тестирования HTTP-хендлеров без реального запуска сервера. Он позволяет создавать моки запросов (NewRequest
) и записывать ответы (NewRecorder
).
Пример:
func TestGetUserHandler(t *testing.T) {
// Создаем мок-запрос к нашему хендлеру
req := httptest.NewRequest(http.MethodGet, "/users/1", nil)
w := httptest.NewRecorder()
// Предположим, что GetUserHandler - это наш http.Handler
GetUserHandler(w, req)
// Проверяем статус-код ответа
if w.Code != http.StatusOK {
t.Errorf("Expected status OK; got %v", w.Code)
}
// Проверяем тело ответа
var user User
if err := json.NewDecoder(w.Body).Decode(&user); err != nil {
t.Fatalf("Could not decode response: %v", err)
}
if user.ID != 1 {
t.Errorf("Expected user ID 1; got %d", user.ID)
}
}
2. Работа с внешними зависимостями (БД, кэши)
Для интеграционных тестов с базами данных (PostgreSQL, MySQL) или кэшами (Redis) лучшей практикой является запуск этих зависимостей в Docker-контейнерах на время теста. Это гарантирует чистое и изолированное окружение.
- Инструменты: Библиотека
testcontainers-go
сильно упрощает управление жизненным циклом Docker-контейнеров прямо из Go-кода.
3. Разделение тестов с помощью Build Tags
Интеграционные тесты обычно медленнее юнит-тестов, поэтому их часто запускают отдельно. Для этого используются build-теги.
-
В начало файла с интеграционным тестом добавляется специальный комментарий:
//go:build integration package my_test
-
Запуск тестов выполняется с указанием тега:
# Запустить только интеграционные тесты go test -v -tags=integration ./... # Запустить все тесты, кроме интеграционных go test -v ./...