Reputation: 2647
I am using https://github.com/go-redis/redis
package to make Redis DB calls.
For unit testing I want to mock these calls. How can I do it?
Upvotes: 16
Views: 17484
Reputation: 347
To mock go-redis, you can use the go-redis/redismock library, which is specifically designed for mocking Go-Redis clients.
Here is an example test to set and get a value:
import "github.com/go-redis/redismock/v9"
// This is how to create a redis mock client:
client, mock := redismock.NewClientMock()
// Define the client.Set method to be called with specific arguments
mock.ExpectSet("key", "value", 0).SetVal("OK")
// Perform the Set operation
ctx := context.Background()
err := db.Set(ctx, "key", "value", 0).Err()
if err != nil {
t.Fatal(err)
}
// Define the client.Get method to be called and return a specific value
mock.ExpectGet("key").SetVal("value")
// Perform the Get operation
val, err := db.Get(ctx, "key").Result()
if err != nil {
t.Fatal(err)
}
if val != "value" {
t.Errorf("expected %s, got %s", "value", val)
}
// Ensure all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unmet expectations: %s", err)
}
Upvotes: -1
Reputation: 779
It's even easier to mock using miniredis than is apparent. You don't need to mock every function like Get, Set, ZAdd, etc. You can start the miniredis
and inject its address to the actual client being used in code (e.g. go-redis) this way:
server := miniredis.Run()
redis.NewClient(&redis.Options{
Addr: server.Addr(),
})
No further mocking would be required. This also enables you to seamlessly use Pipelined()
, TxPipelined()
etc. even though miniredis
doesn't explicitly expose these methods.
Upvotes: 24