go-redis / redismock

Redis client Mock
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
280 stars 60 forks source link

Possible to use as in-memory mock storage #11

Closed ahmetb closed 3 years ago

ahmetb commented 3 years ago

I notice this package is a great substitution for *redis.Client. However all calls to it must be prepared with mock.ExpectGet(..).SetVal(..).

I am hoping to use this as a mock redis implementation in my main application code (where I use redis as a "cache") that just accepts the commands, and ignores them.

So I'm almost looking for an in-memory implementation of *redis.Client (because I don't want to run redis-server to have my app run locally). It does not have to actually store/serve the data.

Does this exist –or is there a way I can use redismock in this way, say something like mock.ExpectAnything().

monkey92t commented 3 years ago

You can try a simpler way (but it does not support all commands):

type hook struct {}

func (h *hook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) {
    cmd.SetErr(redis.Nil)
    return ctx, nil
}
func (h *hook) AfterProcess(_ context.Context, _ redis.Cmder) error {
    return nil
}
func (h *hook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) {
    for _, cmd := range cmds {
        cmd.SetErr(redis.Nil)
    }
    return ctx, nil
}
func (h *hook) AfterProcessPipeline(_ context.Context, _ []redis.Cmder) error {
    return nil
}

func TestRedis() {
    rdb := redis.NewClient(&redis.Options{
        MaxRetries: -2,
    })
    rdb.AddHook(&hook{})
}
monkey92t commented 3 years ago

If you do not want to set a common return value for the command (such as redis.Nil), you can remove the hook

ahmetb commented 3 years ago

That's useful, thanks!

henrikrudstrom commented 3 years ago

there is also miniredis: http://github.com/alicebob/miniredis its an inmemory implementation

ahmetb commented 3 years ago

Actually that's far more useful. Thank you. 🙏