rovy
rovy

Reputation: 2647

How to mock redis connection in Go

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

Answers (3)

Kosy Anyanwu
Kosy Anyanwu

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

Chayan Ghosh
Chayan Ghosh

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

Asalle
Asalle

Reputation: 1337

as @Motakjuq said, create an interface like this

type DB interface {
   GetData(key string) (value string, error)
   SetData(key string, value string) error
}

and implement it with actual redis client (like this) in your code and miniredis in tests.

Upvotes: 1

Related Questions