Я довольно новичок в Go, и у меня возникли некоторые проблемы с написанием тестов, в частности насмешка над ответом функции пакета.
Я пишу библиотеку оболочки для github.com/go-redis/redis
.На данный момент он действительно имеет только лучшие ошибки для сбоев, но он будет расширен за счет отслеживания statsd дальше, но я отвлекся ...
У меня есть следующий пакет go, который я создал
package myredis
import (
"time"
"github.com/go-redis/redis"
errors "github.com/pkg/errors"
)
var newRedisClient = redis.NewClient
// Options - My Redis Connection Options
type Options struct {
*redis.Options
DefaultLifetime time.Duration
}
// MyRedis - My Redis Type
type MyRedis struct {
options Options
client *redis.Client
}
// Connect - Connects to the Redis Server. Returns an error on failure
func (r *MyRedis) Connect() error {
r.client = newRedisClient(&redis.Options{
Addr: r.options.Addr,
Password: r.options.Password,
DB: r.options.DB,
})
_, err := r.client.Ping().Result()
if err != nil {
return errors.Wrap(err, "myredis")
}
return nil
}
Моя проблема в том, что я хочу, чтобы redis.NewClient
вернул макет.Это тестовый код, который я написал, но он не работает:
package myredis
import (
"testing"
"github.com/go-redis/redis"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type redisStatusCmdMock struct {
mock.Mock
}
func (m *redisStatusCmdMock) Result() (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}
type redisClientMock struct {
mock.Mock
}
func (m *redisClientMock) Ping() redis.StatusCmd {
args := m.Called()
return args.Get(0).(redis.StatusCmd)
}
func TestConnect(t *testing.T) {
assert := assert.New(t)
old := newRedisClient
defer func() { newRedisClient = old }()
newRedisClient = func(options *redis.Options) *redis.Client {
assert.Equal("127.0.0.1:1001", options.Addr)
assert.Equal("password", options.Password)
assert.Equal(1, options.DB)
statusCmdMock := new(redisStatusCmdMock)
statusCmdMock.On("Result").Return("success", nil)
clientMock := new(redisClientMock)
clientMock.On("Ping").Return(statusCmdMock)
return clientMock
}
options := Options{}
options.Addr = "127.0.0.1:1001"
options.Password = "password"
options.DB = 1
r := MyRedis{options: options}
result, err := r.Connect()
assert.Equal("success", result)
assert.Equal(nil, err)
}
Я получаю следующую ошибку: cannot use clientMock (type *redisClientMock) as type *redis.Client in return argument
.Я думаю, что прочитал, что мне нужно смоделировать все функции redis.Client
, чтобы иметь возможность использовать его в качестве насмешки в этом случае, но так ли это на самом деле?Кажется, это излишне, и я должен быть в состоянии сделать это каким-то образом.Как мне заставить этот тест работать или мне нужно реструктурировать мой код, чтобы его было легче написать?