ioredis-mock

repository·main·Indexed 19 days ago

https://github.com/stipsan/ioredis-mock

An in-memory emulation of the ioredis library designed for integration testing in environments where a real Redis server is unavailable, such as CI pipelines. It supports standard Redis operations, Pub/Sub channels, custom Lua commands via defineCommand(), and experimental support for Redis Cluster and browser environments. Version 8.13.1 requires ioredis@v5 or higher and uses native Promises.

Tokens
41.6K
Snippets
253
Records
257
Agent score
56%

What's inside ioredis-mock

  1. How Pub/Sub channels work in ioredis-mock

    main

    ioredis-mock supports Redis publish/subscribe channels. Similar to the real ioredis, you typically require two separate client instances: one for publishing and one for subscribing.

    const Redis = require('ioredis-mock')
    const redisPub = new Redis()
    const redisSub = new Redis()
    
    redisSub.on('message', (channel, message) => {
      console.log(`Received ${message} from ${channel}`)
    })
    redisSub.subscribe('emails')
    redisPub.publish('emails', 'clark@daily.planet')
  2. Migrate from v5 to v6: Shared context between instances

    main

    In versions prior to v6, each ioredis-mock instance lived in isolation. Starting with v6, instances share context if they use the same host and port (defaulting to 6379). This makes the mock behave more like a real Redis server.

    Because data persists between instances sharing the same port, you should run flushall between test suites to ensure isolation.

    const Redis = require('ioredis-mock')
    
    // Instances sharing default port 6379 share data
    const redis1 = new Redis()
    const redis2 = new Redis()
    
    // Recommended pattern for test isolation:
    afterEach(done => {
      new Redis().flushall().then(() => done())
    })
  3. Use ioredis-mock in the browser (Experimental)

    main

    An experimental browser build is available. You can import it directly from the package or via unpkg.com.

    import Redis from 'https://unpkg.com/ioredis-mock'
    
    const redis = new Redis()
    redis.set('foo', 'bar')
    console.log(await redis.get('foo'))
  4. Migrate from v6 to v7: Jest integration changes

    main

    The ioredis-mock/jest.js file has been removed. Because ioredis-mock now performs a direct import of Command from ioredis/built/command, the previous Jest workaround is no longer necessary.

    Update your Jest mock:

    -jest.mock('ioredis', () => require('ioredis-mock/jest'))
    +jest.mock('ioredis', () => require('ioredis-mock'))
  5. Install and use ioredis-mock in Node.js

    main

    ioredis-mock emulates ioredis by performing all operations in-memory. It is useful for integration testing in environments where a real Redis server is difficult to set up (e.g., CI, platforms without official Redis releases, or complex Selenium environments).

    You can initialize the mock with pre-existing data using the data option, which is unique to ioredis-mock and does not exist in the standard ioredis library.

    const Redis = require('ioredis-mock')
    const redis = new Redis({
      // `options.data` does not exist in `ioredis`, only `ioredis-mock`
      data: {
        user_next: '3',
        emails: {
          'clark@daily.planet': '1',
          'bruce@wayne.enterprises': '2',
        },
        'user:1': { id: '1', username: 'superman', email: 'clark@daily.planet' },
        'user:2': { id: '2', username: 'batman', email: 'bruce@wayne.enterprises' },
      },
    })
    // Basically use it just like ioredis
  6. Migrate from v7 to v8: Breaking changes

    main

    Upgrading to v8 introduces the following breaking changes:

    1. ioredis@v4 support dropped: The new baseline is ioredis@v5. If you are still on ioredis@v4, stay on ioredis-mock@v7.
    2. PromiseContainer removed: Support for third-party Promise libraries is dropped. The library now uses native Promises exclusively.
  7. Use Redis Cluster (Experimental)

    main

    Experimental support for Redis Cluster is available via Redis.Cluster.

    const Redis = require('ioredis-mock')
    
    const cluster = new Redis.Cluster(['redis://localhost:7001'])
    const nodes = cluster.nodes()
    expect(nodes.length).toEqual(1)
  8. Define custom Lua commands with defineCommand()

    main

    You can extend the mock client by defining custom commands using Lua scripts via the defineCommand(name, definition) method. This allows you to simulate complex Redis logic in your tests.

    Limitations:

    • Does not support dynamic key numbers (passing the number of keys as the first argument).
    • Does not automatically define the [commandName]Buffer companion (e.g., multiplyBuffer).
    • evalsha and script commands are not supported.
    const Redis = require('ioredis-mock')
    const redis = new Redis({ data: { k1: 5 } })
    const commandDefinition = {
      numberOfKeys: 1,
      lua: 'return redis.call("GET", KEYS[1]) * ARGV[1]',
    }
    redis.defineCommand('multiply', commandDefinition)
    
    // Call the new command like an ordinary command
    redis.multiply('k1', 10).then(result => {
      expect(result).toBe(5 * 10)
    })
  9. Execute Lua code directly with eval()

    main

    If you do not want to define a permanent custom command, you can execute Lua code directly using the eval command, just like in a real Redis instance.

    const Redis = require('ioredis-mock')
    const redis = new Redis({ data: { k1: 5 } })
    const result = redis.eval(`return redis.call("GET", "k1") * 10`)
    expect(result).toBe(5 * 10)
  10. Use the ZSCOREBUFFER command

    main

    The zscoreBuffer command is a variant of zscore that returns the result as a Buffer instead of a string. This is useful for low-level protocol simulations or when the consumer expects binary data.

    // Returns the score as a Buffer
    const scoreBuffer = zscoreBuffer(key, member);