> Как написать юнит-тест для функции, которая читает данные из базы и считает среднее? (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.0
for _, v := range values {
sum += v
}
return sum / float64(len(values)), nil
}
// Мок для тестов
type mockProvider struct {
values []float64
err error
}
func (m *mockProvider) GetValues() ([]float64, error) {
return m.values, m.err
}
// Юнит-тест
func TestCalculateAverage(t *testing.T) {
tests := []struct {
name string
provider DataProvider
expected float64
wantErr 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.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью