Install redismock v9
masterEnsure you are using github.com/redis/go-redis/v9 for your redis.Client. Then, install redismock using:
go get github.com/go-redis/redismock/v9repository·master·Indexed 43 days ago
https://github.com/go-redis/redismockA mocking framework for the go-redis v9 client that allows developers to write unit tests for Redis-dependent code without requiring a running Redis server. It supports mocking standard redis.Client and Redis Cluster clients, providing a wide array of Expect... methods to define return values, simulate errors, and verify that command expectations were met.
Ensure you are using github.com/redis/go-redis/v9 for your redis.Client. Then, install redismock using:
go get github.com/go-redis/redismock/v9When defining an expectation using an Expect... method, you must specify what the command should return using the SetVal method on the returned expectation object. The type of SetVal depends on the command being mocked.
Common return types include:
*ExpectedString: Use SetVal(string)*ExpectedInt: Use SetVal(int64)*ExpectedBool: Use SetVal(bool)*ExpectedStatus: Use SetVal(string)*ExpectedStringSlice: Use SetVal([]string)*ExpectedSlice: Use SetVal([]interface{})*ExpectedCmd: Use SetVal(interface{})You can also simulate Redis errors or Nil responses:
SetErr(err error): Sets the error to be returned by the command.RedisNil(): Sets the command to return a redis.Nil error.To mock a standard Redis client, use NewClientMock(). This returns two values: the *redis.Client to be used in your application code, and a ClientMock interface used to define expectations.
client, mock := redismock.NewClientMock()
// Use 'client' in your logic
// Use 'mock' to set expectationsclient, mock := redismock.NewClientMock()To mock a Redis Cluster client, use NewClusterMock(). This returns the *redis.ClusterClient and a ClusterClientMock interface.
client, mock := redismock.NewClusterMock()
// Use 'client' in your logic
// Use 'mock' to set expectationsclient, mock := redismock.NewClusterMock()To mock a standard redis.Client, use redismock.NewClientMock(). This returns a *redis.Client (which you can pass into your application code) and a redismock.Mock object used to define expectations.
Common expectation methods include:
ExpectGet(key): Expects a GET command..RedisNil(): Tells the mock to return a redis.Nil error.ExpectSet(key, value, expiration): Expects a SET command..SetErr(err): Tells the mock to return a specific error.ExpectationsWereMet(): Verifies that all defined expectations were actually called.func TestNewsInfoForCache(t *testing.T) {
db, mock := redismock.NewClientMock()
newsID := 123456789
key := fmt.Sprintf("news_redis_cache_%d", newsID)
// Mocking a scenario where GET returns Nil, and subsequent SET fails
mock.ExpectGet(key).RedisNil()
mock.Regexp().ExpectSet(key, `[a-z]+`, 30 * time.Minute).SetErr(errors.New("FAIL"))
_, err := NewsInfoForCache(db, newsID)
if err == nil || err.Error() != "FAIL" {
t.Error("wrong error")
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
}To mock a Redis Cluster client, use redismock.NewClusterMock(). This returns a cluster client and its corresponding mock object.
clusterClient, clusterMock := redismock.NewClusterMock()The following commands are not supported by the mock implementation:
For redis.Client:
Subscribe / PSubscribeFor redis.ClusterClient:
Subscribe / PSubscribePipeline / TxPipelineWatchExpectFunction... methods to mock Redis Functions (Lua-based) operations, such as loading, deleting, or listing functions.Use UnexpectedCallsWereMade() to detect if any commands were executed that were not explicitly defined in your expectations. It returns a boolean indicating if unexpected calls occurred and a slice of the redis.Cmder objects that were unexpected.
unexpected, calls := mock.UnexpectedCallsWereMade()
if unexpected {
// handle unexpected calls
}ExpectZ... methods to mock Redis Sorted Set (ZSET) operations. These methods return expectation types corresponding to the return values of ZSET commands, such as ExpectedInt, ExpectedFloat, or ExpectedZSlice.Use the following methods on a mock client to set expectations for RedisTimeSeries (TSM) commands. These methods return an *ExpectedMapStringSliceInterface, which allows you to define the expected return values for the command.
// Example: Expecting a TSMRange command
mock.ExpectTSMRange(1625097600, 1625184000, []string{"field1"}).SetVal(map[string][]string{
"field1": {"1625097600", "10"},
})
// Example: Expecting a TSMGet command with options
mock.ExpectTSMGetWithArgs([]string{"field1"}, &redis.TSMGetOptions{})You can modify how the mock matches incoming commands using the following methods:
MatchExpectationsInOrder(b bool): If set to true, commands must be executed in the exact order they were defined in the expectations. Defaults to true.Regexp(): Returns a clone of the mock where command arguments can be matched using regular expressions instead of strict equality.CustomMatch(fn CustomMatch): Returns a clone of the mock that uses a custom function to validate command arguments.// Require strict ordering
mock.MatchExpectationsInOrder(true)
// Use regex for argument matching
regexMock := mock.Regexp()
// Use a custom matching function
customMock := mock.CustomMatch(func(expectArgs, cmdArgs []interface{}) error {
// custom logic
return nil
})