【问题标题】:How to test a RedisClient returned by a promise using Jest and Node.JS如何使用 Jest 和 Node.JS 测试由 Promise 返回的 RedisClient
【发布时间】:2021-07-23 13:09:07
【问题描述】:
// client.js
const getCacheClient = async (configuration) => {
  return new Promise((resolve, reject) => {
    const redisClient = redis.createClient(configuration.port, configuration.host);
    // note that promise is fullfiled or rejected based on redis client events
    redisClient.on('ready', () => resolve(redisClient));
    redisClient.on('error', (redisError) => {
      console.log('Error connecting Redis', redisError.message);
      redisClient.quitAsync();
      return reject(redisError);
    });
  });
};

测试由 promise 返回但解析或拒绝基于事件处理程序的 Redis 客户端的正确方法是什么?

由于解决或拒绝是基于“成功/错误”事件,我不确定如何重新创建事件。我得到一个 '在 jest.setTimeout.Timeout 指定的 10000 毫秒超时内未调用异步回调 - 在 jest.setTimeout.Error 指定的 10000 毫秒超时内未调用异步回调:'

// client.test.js

import client, { __RewireAPI__ as API } from '../client';

describe('get-cache-client', () => {
  const mockBlueprint = { promisifyAll: jest.fn((x) => x) };
  const mockRedisClient = {
    getAsync: jest.fn(),
    setexAsync: jest.fn(),
    on: jest.fn(),
  };
  const mockRedis = {
    createClient: {
      on: jest.fn(),
    },
  };

  beforeEach(() => {
    API.__Rewire__('redis', mockRedis);
    API.__Rewire__('blueprint', mockBlueprint);
  });

  afterEach(() => {
    __rewire_reset_all__();
    mockRedis.createClient.mockReset();
  });

  describe('getCacheClient', () => {
    it('should create a client with the expected parameters', async (done) => {
      const config = {
        host: 'testrediscachehost',
        port: 1234,
        key: 'testrediscachekey',
      };
      mockRedis.createClient.on.mockReturnValue(mockRedisClient);
      const client = await expect(getCacheClient(config));
      // it gets stuck here, promise is never fulfilled or rejected
      // .... tests...
    });
  });
});

【问题讨论】:

    标签: node.js unit-testing redis jestjs


    【解决方案1】:

    我没有看到任何使用 __Rewire__ 东西的理由。

    使用jest.spyOn()jest.restoreAllMocks() 就足够了。

    例如

    client.js:

    import redis from 'redis';
    
    export const getCacheClient = async (configuration) => {
      return new Promise((resolve, reject) => {
        const redisClient = redis.createClient(configuration.port, configuration.host);
        redisClient.on('ready', () => resolve(redisClient));
        redisClient.on('error', (redisError) => {
          console.log('Error connecting Redis', redisError.message);
          redisClient.quit();
          return reject(redisError);
        });
      });
    };
    

    client.test.js:

    import { getCacheClient } from './client';
    import redis from 'redis';
    
    describe('68492493', () => {
      afterEach(() => {
        jest.restoreAllMocks();
      });
      test('should create redis client and be ready', async () => {
        const config = {
          host: 'testrediscachehost',
          port: 1234,
          key: 'testrediscachekey',
        };
        const mRedisClient = {
          on: jest.fn().mockImplementation(function (event, handler) {
            if (event === 'ready') {
              handler();
            }
            return this;
          }),
          quit: jest.fn(),
        };
        const createClientSpy = jest.spyOn(redis, 'createClient').mockReturnValueOnce(mRedisClient);
        await getCacheClient(config);
        expect(createClientSpy).toBeCalledWith(1234, 'testrediscachehost');
        expect(mRedisClient.on).toBeCalledWith('ready', expect.any(Function));
      });
    
      test('should handle error', async () => {
        // Try test by yourself
      });
    });
    

    测试结果:

     PASS  examples/68492493/client.test.ts (8.739 s)
      68492493
        ✓ should create redis client and be ready (4 ms)
    
    -----------|---------|----------|---------|---------|-------------------
    File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -----------|---------|----------|---------|---------|-------------------
    All files  |      75 |      100 |      80 |   66.67 |                   
     client.ts |      75 |      100 |      80 |   66.67 | 8-10              
    -----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        9.548 s, estimated 10 s
    Ran all test suites related to changed files.
    

    【讨论】:

    • 你是绝对正确的。我不需要重新布线。嘿,非常感谢,我想太多了。您的推荐非常有效
    猜你喜欢
    • 2021-06-23
    • 2018-03-24
    • 2019-09-30
    • 2020-04-21
    • 2017-01-24
    • 1970-01-01
    • 2020-10-19
    • 2018-07-06
    • 1970-01-01
    相关资源
    最近更新 更多