node-redis icon indicating copy to clipboard operation
node-redis copied to clipboard

Provide an official mocking library for mocking Node-Redis in Jest tests

Open blagae opened this issue 2 years ago • 9 comments

Description

I am struggling to find a way to combine the modern Redis v4 client with the jest test framework.

This is my production code:

import redis from 'redis';
import config from './config';
import logger from './logger';

const redisClient = redis.createClient(config.redisConfig);
redisClient.on('error', (e) => logger.error(e));

(async () => {
  await redisClient.connect();
})();

export type RedisClient = typeof redisClient;
export default async () => {
  const clone = redisClient.duplicate();
  await clone.connect();
  return clone;
};

Some of my services of course use redis, and when I try to test them, the entire test suite usually fails at startup. This is a project that was migrated from plain JS to TS, from node-redis 3 to 4, and from mocha to jest.

Below are a few scenarios that don't work.

No config added:

FAIL lib/services/tests/area.spec.ts
  ● Test suite failed to run

    TypeError: Cannot read properties of undefined (reading 'createClient')

      4 |
    > 5 | const redisClient = redis.createClient(config.redisConfig);
        |                           ^

      at Object.createClient (lib/redis-client.ts:5:27)

Using the documented scenario with redis-mock:

in package.json

  "jest": {
    "setupFilesAfterEnv": [
      "./jest.setup.redis-mock.js"
    ]
  },

in jest.setup.redis-mock.js

import {jest} from '@jest/globals';
jest.mock('redis', () => jest.requireActual('redis-mock'));

Gives the error:

FAIL lib/services/tests/area.spec.ts
    TypeError: redisClient.connect is not a function

       8 | (async () => {
    >  9 |   await redisClient.connect();
         |                     ^
      10 | })();

      at connect (lib/redis-client.ts:9:21)
      at asyncGeneratorStep (lib/redis-client.ts:3:31)

Messing around in the jest setup file usually ends up with the entire library being undefined, etc.

blagae avatar Jun 22 '23 20:06 blagae

i have the same issue

berthoogsteyns avatar Jun 29 '23 11:06 berthoogsteyns

Hi @blagae Thanks for reporting this issue. Redis-mock package is outdated and doesn't work properly with Node-Redis v4. We plan to provide an official mocking library for Node-redis v5. I'll post an update here once we have a preview release to test.

Please stay tuned.

uglide avatar Jun 29 '23 12:06 uglide

Hi @uglide

Thanks for your reply. If you're still accepting and/or starting feature requests such as this for the new version, it looks like the release of v5 is not for the very near future. Is there a way that I can follow the current goals, the progress towards it, and/or some milestones ? I haven't found a comprehensive overview.

Alternatively, do you know why the node-redis library doesn't allow being used in a jest test run ? Is it something with an env variable or another type of global flag ? I wouldn't mind messing around with it a bit, including actually running a Redis server to test my code.

blagae avatar Jun 29 '23 13:06 blagae

Any updates on this? Having similar issues with migrating to node redis v4 - a big portion of our existing tests that rely on redis-mock fail. It would be great to get something from within the library itself, or any guidance on how to best mock the client in the new rendition of the library. Thanks!

EvanSanderson avatar Aug 22 '24 20:08 EvanSanderson

Bumping this; I am now running into the same issue with redis-mock (or any other mocking libraries) with redis v4.

adamperez avatar Dec 09 '24 17:12 adamperez

It's the same situation for me 🙃 - Trying to upgrade to redis v4 but I am having issues with our tests

cefeboru avatar Jan 09 '25 00:01 cefeboru

bumping this up! It's such a pain 😇

ibukunoluwayomi avatar Jan 09 '25 20:01 ibukunoluwayomi

For anyone else coming across this, it isn't a pretty fix but it is a work around until there is a proper mock as mentioned is coming in v5.

in my jest.config.js I have

module.exports = {
  ...,
  setupFilesAfterEnv: ['./jest.setup.redis-mock.js', 'jest-extended/all'],
}

Then in the jest.setup.redis-mock.js file I have

jest.mock('redis', () => ({
  createClient: jest.fn().mockReturnValue({
    on: jest.fn(),
    connect: jest.fn(),
    get: jest.fn(),
    set: jest.fn(),
    expire: jest.fn(),
  }),
}));

I'm actually not using redis-mock in the end. Where I need explicit return values from the get, set, or expire I mock the wrapping functions to return a specific value. The functions here just work to catch any additional un-mocked usages.

I am trying to set up tests. Node-Redis v5 is out, so do we have any mocking libraries for v5?

the-nishant-singh avatar Jul 25 '25 09:07 the-nishant-singh