Golang — Mock для sqlx драйвера базы данных

Для написания юнит тестов часто требуется «мокать» часть зависимостей, одна из самых распространенных — соединение и операции с базой данных. Если нет возможности использовать внедрение зависимости и использовать интерфейсы типа ExecerContext на входе функции то в дело вступают не совсем чистые хаки в виде Monkey patching.

Патчим открытие соединения sqlx.Connect при помощи библиотеки bou.ke/monkey:

guard = monkey.Patch(sqlx.Connect, func(driverName, dataSourceName string) (*sqlx.DB, error) {
		guard.Unpatch()
		defer guard.Restore()
		db := &sqlx.DB{}

		return db, nil
	})

Далее патчим defer sqlx.Close:

var dbSQL *sql.DB
guard = monkey.PatchInstanceMethod(reflect.TypeOf(dbSQL), "Close", func(db *sql.DB) error {
		guard.Unpatch()
		defer guard.Restore()

		return nil
	})

Ну и при выполнении операций, sqlx.Exec:

guard = monkey.PatchInstanceMethod(reflect.TypeOf(db), "Exec", func(db *sqlx.DB, query string, args ...interface{}) (sql.Result, error) {
		guard.Unpatch()
		defer guard.Restore()

		return nil, nil
	})

Теперь мы можем писать тесты на часть кода, которая работает напрямую с базой данных:

...
db, err := sqlx.Connect("postgres", fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable password=%s", dbHost, dbPort, dbUser, dbName, dbPass))
	if err != nil {
		return err
	}
	defer db.Close()
...

_, err := db.Exec(sql, args...)
	if err != nil {
		return err
	}
...

 

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *