Установка
go install github.com/gomocker/gomocker@latest
Создание тестового конфига
gomocker touch
Команда выше создаст файла gomocker.yml в рабочей директории.
Стркутура конфигурационного файла
# gomocker.yml
# название пакета, которое будет записано в сгенерированный файл
package: main
# файл, куда записать сгенерированный код
output: gomocker_output.go
# интерфейсы, для которых нужно сгенерировать моки
mocks:
# указывается полный импорт пакета (например, github.com/minio/minio-go/v7, или в случае с io просто io)
# и список интерфейсов из этого пакета, для которых нужно сгенерировать код.
io:
- Reader
- Writer
- ReadWriter
math/rand:
- Source
# опциональная секция для правильной настройки имортов в сгенерированном коде
# например, если у нас где-то используется структура minio.Client, то
# gomocker будет пытаться импортировать minio как github.com/minio/minio-go
# в то время как правильный импорт будет github.com/minio/minio-go/v7
imports:
io: io
rand: math/rand
minio: github.com/minio/minio-go/v7
Генерация
gomocker
Команда выше сгенерирует код для создания моков и запишет его в файл, указанный в gomocker.yml
Gomocker генерирует конструкторы для создания интерфейсов.
На вход конструктору передается структура, все поля которой являются фукнциями аналогичными фукнциям интерфейса
main.go
package main
import (
"fmt"
)
type Auth interface {
Login(login string, password string) (err error)
}
gomocker_output.go
// Code generated by gomocker v1.2.1. DO NOT EDIT.
//
// For more information see github.com/gomocker/gomocker
package main
// Implementations
type (
authImpl struct{ behavior AuthBehavior }
)
// Check
var (
_ Auth = &authImpl{}
)
// NewAuth creates mocked implementation of Auth interface
func NewAuthMock(behavior AuthBehavior) Auth {
return &authImpl{
behavior: behavior,
}
}
type AuthBehavior struct {
Login func(login string, password string) (err error)
}
func (aeiouy *authImpl) Login(login string, password string) (err error) {
if aeiouy.behavior.Login != nil {
return aeiouy.behavior.Login(login, password)
}
return
}
Использование
package main
import (
"fmt"
)
type Auth interface {
Login(login string, password string) (err error)
}
func main() {
auth := NewAuthMock(AuthBehavior{
Login: func(login string, password string) (err error) {
fmt.Println("Функия Login была вызана")
return nil
},
})
if err := auth.Login("admin", "admin"); err != nil {
fmt.Println(err)
}
}
Плюшки
type Test1 interface {
Method1()
}
type Test2 = Test1
type Test3 = Test2
type Test = Test3
- Поддержка вложенных интерфейсов
type Test1 interface {
Method1()
}
type Test2 interface {
Method2()
}
type Test interface {
Test1
Test2
}
- Не используется рефлексия и interface{}. Аргументы функций сохраняют свой тип
- Если аргумент функции именован, то имя также сохранится.