redismock for go-redis

repository·master·Indexed 43 days ago

https://github.com/go-redis/redismock

A 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.

Tokens
3.7K
Snippets
12
Records
32
Agent score
56%

What's inside redismock

  1. Set return values for mocked commands

    master

    When 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.
  2. Create a mock Redis client

    master

    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 expectations
    client, mock := redismock.NewClientMock()
  3. Create a mock Redis Cluster client

    master

    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 expectations
    client, mock := redismock.NewClusterMock()
  4. Quick Start: Mocking a redis.Client

    master

    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)
    	}
    }
  5. Check for unexpected Redis calls

    master

    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
    }
  6. Mock Sorted Set commands with ExpectZ...

    master
    Use the 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.
  7. Mock TSMSearch commands with ExpectTSMRange and ExpectTSMGet

    master

    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{})
  8. Configure command matching behavior

    master

    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
    })