> Как написать юнит-тест для функции, которая читает данные из базы и считает среднее? (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Black Wall Group (BWG)
Стек: Go
> Пример ответа
Для тестирования функции, читающей данные из базы и вычисляющей среднее, нужно изолировать её от реальной БД с помощью интерфейса и моков. Вот пример на Go:
GO// Определяем интерфейс для работы с БДtype DataProvider interface {GetValues() ([]float64, error)}// Функция, которую тестируемfunc CalculateAverage(provider DataProvider) (float64, error) {values, err := provider.GetValues()if err != nil {return 0, err}if len(values) == 0 {return 0, nil // или ошибка, по требованиям}sum := 0.0for _, v := range values {sum += v}return sum / float64(len(values)), nil}// Мок для тестовtype mockProvider struct {values []float64err error}func (m *mockProvider) GetValues() ([]float64, error) {return m.values, m.err}// Юнит-тестfunc TestCalculateAverage(t *testing.T) {tests := []struct {name stringprovider DataProviderexpected float64wantErr bool}{{name: "нормальные данные",provider: &mockProvider{values: []float64{10, 20, 30}},expected: 20.0,wantErr: false,},{name: "пустой список",provider: &mockProvider{values: []float64{}},expected: 0.0,wantErr: false,},{name: "ошибка БД",provider: &mockProvider{err: errors.New("db error")},expected: 0.0,wantErr: true,},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {result, err := CalculateAverage(tt.provider)if (err != nil) != tt.wantErr {t.Errorf("ошибка = %v, wantErr = %v", err, tt.wantErr)}if result != tt.expected {t.Errorf("результат = %v, ожидалось %v", result, tt.expected)}})}}
Ключевые моменты:
- Используем интерфейс
DataProviderдля абстракции от БД. - Мок возвращает заранее заданные данные или ошибку.
- Тест проверяет несколько сценариев: успех, пустые данные, ошибку.
- Для более сложных случаев можно использовать библиотеки вроде
gomockилиtestify/mock.
> Похожие задачи по Go
Готов ли ты писать код сейчас?
С какими паттернами проектирования приходилось работать в Go?
Почему важно валидировать входные данные
Что происходит, если фича не успела быть сделана в спринт и как переносится задача
> Похожие задачи по backend
Готов ли ты писать код сейчас?
С какими паттернами проектирования приходилось работать в Go?
Почему важно валидировать входные данные
Что происходит, если фича не успела быть сделана в спринт и как переносится задача
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью