Назад к статьям

Тестирование в Go: юнит-тесты, моки и интеграция

Практический подход к тестированию Go-кода: table-driven tests, testify, моки через интерфейсы, testcontainers.

Table-Driven Tests

Идиоматический подход в Go. Один тест-кейс — одна строка в таблице:

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive", 2, 3, 5},
        {"negative", -1, -2, -3},
        {"zero", 0, 0, 0},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            assert.Equal(t, tt.expected, result)
        })
    }
}

Моки через интерфейсы

Go делает мокирование естественным через интерфейсы. Определяйте минимальные интерфейсы и подставляйте тестовые реализации:

type mockRepo struct {
    users map[int64]*User
}

func (m *mockRepo) GetByID(_ context.Context, id int64) (*User, error) {
    user, ok := m.users[id]
    if !ok {
        return nil, ErrNotFound
    }
    return user, nil
}

Интеграционные тесты с testcontainers

Поднимайте реальную PostgreSQL в Docker прямо из тестов. Никаких sqlite-подделок — тестируйте с реальной базой.

Похожие статьи

Go · Architecture · API

Проектирование высоконагруженных API на Go

Разбираем архитектурные паттерны и подходы к созданию API, способного обрабатывать миллионы запросов.

Go · Clean Architecture · Best Practices

Чистая архитектура в Go: от теории к практике

Как применить принципы Clean Architecture в Go-проекте и не превратить код в Java-подобный boilerplate.