Go: запустить тест из нескольких пакетов с инициализацией БД
У меня есть проект GO с такой структурой проекта (несколько пар файлов такого типа в каждом пакете).
- api
- userHandler.go
- userHandler_test.go
- database
- user.go
- user_test.go
Внутри user.go у меня есть структура User и функции для создания / получения / обновления пользователя (я использую GORM, но это не проблема). В user_test.go.
Я хотел бы очистить БД (со всеми данными, удаленными или в определенном состоянии) для каждого отдельного файла, поэтому я попытался создать 1 комплект (используя Testify) для каждого файла, затем использовать функцию SetupSuite, но поведение кажется не детерминированным, и, вероятно, я делаю что-то не так.
Итак, мои вопросы:
- Какой лучший способ иметь соединение с БД? Использование глобальной переменной является лучшим вариантом?
- Каков наилучший способ создать таблицы в БД один раз, а затем инициализировать БД с пользовательскими данными перед каждым запуском file_test.go?
Прямо сейчас у меня тоже странная ошибка: бег
go test path/package1
go test path/package2
Все отлично работает, но если я запустлю (для тестирования всех пакетов)
cd path && go test ./...
У меня есть ошибки, которые не являются детерминированными, поэтому я предполагаю, что соединение с БД не обрабатывается должным образом
1 ответ
Если твой api
пакет зависит от вашего database
пакет (который кажется), то ваш api
пакет должен иметь способ предоставить пул соединений с базой данных (например, *sql.DB
) к нему.
В ваших тестах на api
пакет, вы должны просто передать в инициализированный пул (возможно, с предварительно заполненной тестовой схемой / приборами), который вы можете использовать. Это может быть глобальная инициализация в init()
для api
пакет или setup()
а также defer teardown()
шаблон в каждой тестовой функции.
Вот первый (самый простой) подход, когда вы просто создаете общую базу данных и схему для своих тестов.
package database
import testing
var testDB *sql.DB
// This gets run before your actual test functions do.
func init() {
var err error
db, err = sql.Open(...)
if err != nil {
log.Fatalf("test init failed: %s", err)
}
_, err := db.Exec(`CREATE TABLE ....`)
if err != nil {
log.Fatalf("test schema creation failed: %s", err)
}
}
Несколько советов:
- Вы также можете позвонить
setup()
Функция может создать таблицу со случайным суффиксом и вставить ваши тестовые данные, чтобы ваши тесты не использовали одну и ту же тестовую таблицу (и, следовательно, рискуют конфликтовать или полагаться друг на друга). Захватите это имя таблицы и поместите его в свойdefer teardown()
функция. - https://medium.com/@benbjohnson/structuring-applications-in-go-3b04be4ff091 стоит прочитать для некоторых дополнительных перспектив.