Redis client Mock Provide mock test for redis query

Redis client Mock Build Status

Provide mock test for redis query, Compatible with github.com/go-redis/redis/v8

Install

Confirm that you are using redis.Client the version is github.com/go-redis/redis/v8

go get github.com/go-redis/redismock/v8

Example

More examples: https://github.com/go-redis/redismock/blob/v8/example/example.go

var ctx = context.TODO()

func NewsInfoForCache(redisDB *redis.Client, newsID int) (info string, err error) {
	cacheKey := fmt.Sprintf("news_redis_cache_%d", newsID)
	info, err = redisDB.Get(ctx, cacheKey).Result()
	if err == redis.Nil {
		// info, err = call api()
		info = "test"
		err = redisDB.Set(ctx, cacheKey, info, 30 * time.Minute).Err()
	}
	return
}

func TestNewsInfoForCache(t *testing.T) {
	db, mock := redismock.NewClientMock()

	newsID := 123456789
	key := fmt.Sprintf("news_redis_cache_%d", newsID)

	// mock ignoring `call api()`

	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)
	}
}
Comments
  • Possible to use as in-memory mock storage

    Possible to use as in-memory mock storage

    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().

  • Problems On `CustomMatch` and `Regexp`

    Problems On `CustomMatch` and `Regexp`

    Sorry to take your precious time to help me.

    1. problem codes
    import "github.com/go-redis/redis/v8" //@v8.11.0
    import "github.com/go-redis/redismock/v8"  // @8.0.6
    // ...
    db, mock := redismock.NewClientMock()
    mock.Regexp().ExpectHSet("somekey", `.*`).SetErr(nil)
    mock.CustomMatch(func(expected, actual []interface{}) error {return nil}).ExpectHSet("somekey", "").SetErr(nil)
    
    1. What I expect I want the two mock can fulfill all Hsets. No matter what I give them, they should return normally nil.

    2. What I got

    parameters do not match expectation '[somekey .*]', but call to cmd '[somekey field1 value1 field2 value2]'

    1. comment

    I searched the Internet but found nothing about this two functions, I am not sure whether it is valid to use dot and star in the regexp. So help me please! Feel Free to comment.

  • Checking a hash set created with map is failing

    Checking a hash set created with map is failing

    In one of our applications, we are using HSet to create a Redis hash map. We've been using the map syntax:

    cmd, err := redisCli.HSet("key", map[string]interface{}{"1": "one", "2": "two"})
    

    The request is later unpacked into a slice of arguments (which is native for Redis). But as it was passed as a map, the order every time is different. Then in the mock.match function we iterate over the list of expected args and comparing it to the list of cmd args. This function accesses the elements by index, so chances of getting a match decrease with each new item added into the hash :smile:

    Workaround: Use the slice syntax instead:

    cmd, err := redisCli.HSet("key", []string{"1", "one", "2", "two"})
    

    It is more confusing but works :slightly_smiling_face:

    I'm not really sure what could be a good approach to handle this :confused: Possible solutions on my mind:

    • Give the option to ignore an order of the argument pairs in tests. The same way as it is done with the mock.MatchExpectationsInOrder(true) option
    • Add a check in the match function to ignore an order of the pairs if the called operation supports map syntax
  • Empty result in HGET operation in TxPipelined

    Empty result in HGET operation in TxPipelined

    Hello, I have already asked the question about it on StackOverflow, but I have a strong suspicion that it may be a bug. I'm mocking an HGET operation, but when I call this operation inside a TxPipelined, the result is empty. It doesn't return an error either, like it would do if this was a mock expectation setup error. Here is the code that reproduces my problem:

    package test
    
    import (
        "context"
        "testing"
        "github.com/go-redis/redis/v8"
        "github.com/go-redis/redismock/v8"
    )
    
    func TestMock(t *testing.T) {
        ctx := context.TODO()
    
        db, mock := redismock.NewClientMock()
        mock.ExpectWatch("key")
        mock.ExpectTxPipeline()
        mock.ExpectHGet("key", "field").SetVal("VALUE")
    
        var result string
        db.Watch(ctx, func(tx *redis.Tx) error {
            _, err := tx.TxPipelined(ctx, func(p redis.Pipeliner) error {
                // Here I'd expect r to be "VALUE"
                r, err := p.HGet(ctx, "key", "field").Result()
                t.Logf("Result: '%s', error: %+v", r, err)
                result = r
                return err
            })
    
            return err
        }, "key")
    
        if result != "VALUE" {
            t.Errorf("Expected result to be VALUE, got %s", result)
        }
    }
    

    The test fails with the error:

    --- FAIL: TestMock (0.00s)
        redis_test.go:26: Result: '', error: <nil>
        redis_test.go:36: Expected result to be VALUE, got ''
    

    Without a pipeline, the code works like expected.

  • How to test command redis 'SetArgs'

    How to test command redis 'SetArgs'

    my production code is

    setArgs := redis.SetArgs{
      ExpireAt: time.UnixMilli(minTime),
      }
    setCmd := c.redis.SetArgs(ctx, "counter_slug_pause_ssoid_day, "1", setArgs)
    

    and in unit test is

    clientMock.CustomMatch(func(expected, actual []interface{}) error {
    		assert.Equal(t.T(), expected[0], actual[0])
    		assert.Equal(t.T(), expected[1], actual[1])
    		assert.Equal(t.T(), expected[2], actual[2])
    		assert.Equal(t.T(), "paxt", actual[3])
    		return nil
    	}).ExpectSet("counter_slug_pause_ssoid_day, "1", 0).SetVal("ok")
    

    when run found error parameters do not match, expectation '[set counter_slug_pause_ssoid_day 1]', but call to cmd '[set counter_slug_pause_ssoid_day 1 exat 0]'

    what is the best way to stub 'SetArgs' command

  • 过期时间如何进行通配

    过期时间如何进行通配

    比如ExpectSet这种,一定要设置一个过期时间,但是代码中有些过期时间是随机的导致匹配不上。 报错如下 args not DeepEqual, expectation: '0', but gave: '48308' expire是否可以像value一样用regexp通配? 或者用什么方式不用DeepEqual?

  • Can't be displayed on pkg.go.dev

    Can't be displayed on pkg.go.dev

    Hiya, I just wanted to add a feature request to be able to find this library on pkg.go.dev, and maybe a link to it in README. Currently it is not displayed due to licence restrictions. Thank you.

  • Support for TxPipeline

    Support for TxPipeline

    What is the best way of mocking client.TxPipeline? When expectations are define for the following: HSet, ZAddNX

    pipe := client.TxPipeline()
    pipe.HSet
    pipe.ZAddNX
    pipe.Exec()
    

    the following error is returned: call to cmd '[multi]' was not expected

  • Configure Renovate

    Configure Renovate

    WhiteSource Renovate

    Welcome to Renovate! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.

    :vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.


    Detected Package Files

    • go.mod (gomod)

    Configuration Summary

    Based on the default config's presets, Renovate will:

    • Start dependency updates only once this onboarding PR is merged
    • Separate major versions of dependencies into individual branches/PRs
    • Do not separate patch and minor upgrades into separate PRs for the same dependency
    • Upgrade to unstable versions only if the existing version is unstable
    • Raise PRs immediately (after branch is created)
    • If semantic commits detected, use semantic commit type fix for dependencies and chore for all others
    • Keep existing branches updated even when not scheduled
    • Disable automerging feature - wait for humans to merge all PRs
    • Ignore node_modules, bower_components, vendor and various test/tests directories
    • Autodetect whether to pin dependencies or maintain ranges
    • Rate limit PR creation to a maximum of two per hour
    • Limit to maximum 20 open PRs at any time
    • Group known monorepo packages together
    • Use curated list of recommended non-monorepo package groupings
    • Ignore wrongly tagged actions/setup-node v2 releases
    • Ignore spring cloud 1.x releases

    :abcd: Would you like to change the way Renovate is upgrading your dependencies? Simply edit the renovate.json in this branch with your custom config and the list of Pull Requests in the "What to Expect" section below will be updated the next time Renovate runs.


    What to Expect

    It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.


    :question: Got questions? Check out Renovate's Docs, particularly the Getting Started section. If you need any further assistance then you can also request help here.


    This PR has been generated by WhiteSource Renovate. View repository job log here.

  • Not able to mock setting json serialized data

    Not able to mock setting json serialized data

    Hi,

    I am running into issues mocking setting json serialized data for value, tried regex and that didn't work either, throws parameters do not match, expectation error with or without regex.

    Here are a couple of examples of how I tried to mock setting json serialized data value: mock.Regexp().ExpectSet(key, "(.+)", 5*time.Minute).SetVal("hey") mock.Regexp().ExpectSet(key, "(\\[[\\d\\s]+\\])", 5*time.Minute).SetVal("hey")

    Please let me know if I missed anything.

  • support for client.Watch

    support for client.Watch

    Similar to issue #2, can we have support for Watch?

    I have code like:

    txf := func(tx *redis.Tx) error {
    	val, err := tx.Get(ctx, "mykey").Int64()
    	err = tx.Set(ctx, "mykey", val + 1, 0).Err()
    }
    
    err := client.Watch(ctx, txf, "mykey")
    

    If my test code uses mock.ExpectGet("mykey") then I get:

    parameters do not match, expectation '[get mykey]', but call to cmd '[watch mykey]'
    

    I don't see anything in the code that will expect a WATCH. Is there a way to achieve this or does it need a patch?

    Thank you.

  • Add support for go-redis v9

    Add support for go-redis v9

    Adding support for go-redis/v9

    NOTES

    • go.mod has 'github.com/dtsulik/redismock' instead of 'github.com/go-redis/redismock'
    • ExpectZAddNXCh/XXCh/IncrNX/IncrXX where reimplemented with ZAddArgs and ZAddArgsIncr instead of testing Args variant with bunch of options.
    • All processing hooks (Before/After, BeforePipeline/AfterPipeline) are replaced with single ProcessHook in go-redis/v9 hence only one hook in mock.go.
  • Support for ExpectLPopCount (or other ExpectXXXCount) methods

    Support for ExpectLPopCount (or other ExpectXXXCount) methods

    redismock is awesome and I was glad I found it. But after I made some time investments and refactored my project to use it, I found that some of the methods are not supported by redismock yet. One example is ExpectLPopCount. Are there any plans to support them. I would be glad to open a PR if that works

  • How to mock getDel

    How to mock getDel

    First of all thanks for your work.

    I have been using your lib and it work pretty good but now I have one function using the GetDel from "github.com/go-redis/redis/v8" and I can't find any mock.ExpectGetDel or something similar.

    How to mock the getDel response?

    Best regards

  • How to mock github.com/go-redis/redis/v9

    How to mock github.com/go-redis/redis/v9

    redismock only seems to be available for go-redis/redis/v8, but we are using go-redis/redis/v9. Strangely, I haven't been able to find any discussions about this. Is this because v9 is still in beta perhaps?

GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right away.

GoBigdis GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right

Apr 27, 2022
Bxd redis benchmark - Redis benchmark tool for golang

使用 redis benchmark 工具, 测试 10 20 50 100 200 1k 5k 字节 value 大小,redis get set 性能。 r

Jan 22, 2022
redis client implement by golang, inspired by jedis.

godis redis client implement by golang, refers to jedis. this library implements most of redis command, include normal redis command, cluster command,

Dec 6, 2022
Go client for Redis

Redigo Redigo is a Go client for the Redis database. Features A Print-like API with support for all Redis commands. Pipelining, including pipelined tr

Jan 1, 2023
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 1, 2023
Go Redis Client

xredis Built on top of github.com/garyburd/redigo with the idea to simplify creating a Redis client, provide type safe calls and encapsulate the low l

Sep 26, 2022
godis - an old Redis client for Go

godis Implements a few database clients for Redis. There is a stable client and an experimental client, redis and exp, respectively. To use any of the

Apr 16, 2022
Google Go Client and Connectors for Redis

Go-Redis Go Clients and Connectors for Redis. The initial release provides the interface and implementation supporting the (~) full set of current Red

Oct 25, 2022
Redis client library for Go

go-redis go-redis is a Redis client library for the Go programming language. It's built on the skeleton of gomemcache. It is safe to use by multiple g

Nov 8, 2022
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 4, 2023
Redisx: a library of Go utilities built on the redigo redis client library

redisx redisx is a library of Go utilities built on the redigo redis client libr

Dec 24, 2021
Redis client for Golang
Redis client for Golang

Redis client for Golang To ask questions, join Discord or use Discussions. Newsl

Dec 23, 2021
Redis client for Golang
Redis client for Golang

Redis client for Golang Discussions. Newsletter to get latest updates. Documentation Reference Examples RealWorld example app Other projects you may l

Dec 30, 2021
pogo is a lightweight Go PostgreSQL internal state query engine.

pogo is a lightweight Go PostgreSQL internal state query engine. It focuses on the data that are highly dynamic in nature, and provides some conv

Sep 19, 2021
High-performance framework for building redis-protocol compatible TCP servers/services

Redeo The high-performance Swiss Army Knife for building redis-protocol compatible servers/services. Parts This repository is organised into multiple

Jan 4, 2023
Simple key-value store abstraction and implementations for Go (Redis, Consul, etcd, bbolt, BadgerDB, LevelDB, Memcached, DynamoDB, S3, PostgreSQL, MongoDB, CockroachDB and many more)

gokv Simple key-value store abstraction and implementations for Go Contents Features Simple interface Implementations Value types Marshal formats Road

Dec 24, 2022
Redis Sorted Sets Benchmark

redis-zbench-go Redis Sorted Sets Benchmark Overview This repo contains code to trigger load ( ZADD ) or query (ZRANGEBYLEX key min max) benchmarks, w

May 18, 2021
Use Redis' MONITOR to draw things in a terminal
Use Redis' MONITOR to draw things in a terminal

Redis Top Redistop uses MONITOR to watch Redis commands and shows per command and per host statistics. Because MONITOR streams back all commands, its

Aug 30, 2022
Examples and code to assign a name to your MongoDB, MySQL, PostgreSQL, RabbitMQ, and redis connection.
Examples and code to assign a name to your MongoDB, MySQL, PostgreSQL, RabbitMQ, and redis connection.

your connection deserves a name ?? When your app interacts with an external system, assign a name to the connection. An external system in this contex

Dec 14, 2022