Closed prvn closed 8 years ago
Hi @prvn,
The redis package is not designed to be mockable
, if you want to mock it you will need to create your own mockable
wrapper.
Here you have an example:
package mock
import (
"errors"
"testing"
"gopkg.in/redis.v3"
)
type Client struct {
base redis.Client
}
func (c *Client) ZAdd(key string, members ...redis.Z) IntCmdInterface {
return c.base.ZAdd(key, members...)
}
func (c *Client) ZRem(key string, members ...string) IntCmdInterface {
return c.base.ZRem(key, members...)
}
type ClientInterface interface {
ZAdd(key string, members ...redis.Z) IntCmdInterface
ZRem(key string, members ...string) IntCmdInterface
}
type ClientMock struct {
Mock
}
func (m *ClientMock) ZAdd(key string, members ...redis.Z) IntCmdInterface {
ret := m.Called(key, members)
return ret.Get(0).(IntCmdInterface)
}
func (m *ClientMock) ZRem(key string, members ...string) IntCmdInterface {
ret := m.Called(key, members)
return ret.Get(0).(IntCmdInterface)
}
type IntCmdInterface interface {
Result() (int64, error)
}
type IntCmdMock struct {
Mock
}
func (m *IntCmdMock) Result() (int64, error) {
ret := m.Called()
return ret.Int64(0), ret.Error(1)
}
func TestRedis(t *testing.T) {
client := ClientMock{}
cmd1 := &IntCmdMock{}
cmd2 := &IntCmdMock{}
cmd3 := &IntCmdMock{}
cmd1.When("Result").Return(int64(123), nil)
cmd2.When("Result").Return(int64(456), nil)
cmd3.When("Result").Return(int64(0), errors.New("an error"))
client.When("ZAdd", "foo", Any).Return(cmd1)
client.When("ZRem", "bar", Any).Return(cmd2)
client.When("ZRem", "zar", Any).Return(cmd3)
ret := client.ZAdd("foo", redis.Z{1.00, "member"})
if i, err := ret.Result(); i != 123 || err != nil {
t.Fatal("Result is not 123")
}
ret = client.ZRem("bar")
if i, err := ret.Result(); i != 456 || err != nil {
t.Fatal("Result is not 456")
}
ret = client.ZRem("zar")
if i, err := ret.Result(); i != 0 || err == nil || err.Error() != "an error" {
t.Fatal("error is not `an error`")
}
}
That was super helpful! Thanks @maraino
@prvn And of course as you're doing your own wrapper you can simplify the mock if you do things like:
func (c *Client) ZAdd(key string, members ...redis.Z) (int64, error) {
return c.base.ZAdd(key, members...).Result()
}
I was thinking about the same, so that I can avoid mocking all the Result() functions of each
Hello, I am not sure how to ask a question, so opening a issue.
I am trying to mock a chain of function calls and i am not really getting how to do it from the documentation. Hope you can help me.
I am mocking redis client ("gopkg.in/redis.v3")
All calls to this API looks something like below
redis.Client.ZAdd("test", data...).Result() redis.Client.ZRem("test", data...).Result()
Result() in ZAdd case belongs to struct *redis.IntCmd and Result() in ZRem case belongs to some other struct
How can I mock these API's ?
Appreciate your help