Оригинал:
nathan leclaire,
https://nathanleclaire.com/blog/2015/10/10/interfaces-and-composition-for-effective-unit-testing-in-golang/ 10.10.2015
К чему призывает автор:
1. Используйте интерфейсы GO - это удобно в работе, широко используется в стандартной библиотеке, и упрощает тестирование, избавляя от использование mock и stub библиотек.
2. Составляйте высокоуровневые интерфейсы через композицию (встраивание).
3. Будьте хорошо знакомы с go test и пакетом
testing Где, как применить?
1. Когда вам нужно подменить часть кода и вернуть заранее известные данные - просто напишите еще одну реализацию интерфейса прямо в тесте и используйте ее вместо замещаемой.
Пример кода см. в
оригинале раздел «Example #2: Using an interface to mock results»
2. Тестирование объемной структуры - если в структуре много методов, выделяйте несколько небольших интерфейсов связанных по смыслу, так вы сможете протестировать отдельные части структуры. Когда есть несколько интерфейсов, мы можем писать реализацию для каждой части отдельно и тестировать по частям.
Пример кода см. в
оригинале раздел «Example #3: Using composition to test a large struct». Вкратце, автор один интерфейс
type Job interface {
Log(...interface{})
Suspend() error
Resume() error
Run() error
}, разделил на 2 маленьких: Logger, SuspendResumer - и сделал составной интерфейс :
type Job interface {
Logger
SuspendResumer
Run() error
}
3. Использование и подмена стандартной библиотеки - например, нам нужно сравнить сообщения в логе, а использован стандартный пакет log. Это можно сделать, т.к. пакет log может направить вывод на другую реализацию писателя методом log.SetOutput(io.Writer).
Пример кода см. в
оригинале раздел «Example #4: Using and faking standard library functionality», часть кода ниже:
logReader, logWriter := io.Pipe()
bufLogReader := bufio.NewReader(logReader)
log.SetOutput(logWriter)
Кому рассказать?
Трем коллегам.