redis-sessions 函数的 Jest 模拟

时间:2021-04-22 20:32:14

标签: node.js typescript redis jestjs mocking

我想模拟 redis-session 函数。

static async createSession(userData: string, userId: Uuid, ipAddress: string = 'NA'): Promise<string> {
try {
  const rs = this.getRedisConnection();
  return new Promise<string>((resolve, reject): void => {
    rs.create(
      {
        app: Configs.rsSessionApp,
        id: userId,
        ip: ipAddress,
        ttl: Configs.rsDefaultTtl,
        d: {
          data: userData,
        },
      },
      (err: object, resp: { token: string }): void => {
        if (resp !== undefined && resp.token.length > 0) {
          return resolve(resp.token);
        }

        if (err != null) {
          reject(err);
        }
      },
    );
  });
} catch (error) {
  return Promise.reject(error.message);
}

}

我想让这一行执行 (err: object, resp: { token: string }): void => {} 如何使用 Jest 单元测试来实现或解决这个问题? 另一个抛出错误的单元测试。

1 个答案:

答案 0 :(得分:0)

try...catch... 无法捕捉到异步代码的异常,可以去掉。

您可以使用 jest.spyOn(object, methodName) 模拟 RedisSession.getRedisConnection() 方法并返回模拟的 redis 连接。然后,mock rs.create() 方法的实现,你可以在你的测试用例中得到匿名回调函数。

最后,使用模拟参数手动调用匿名回调函数。

例如

index.ts

import RedisSessions from 'redis-sessions';

interface Uuid {}

export class RedisSession {
  static async createSession(userData: string, userId: Uuid, ipAddress: string = 'NA'): Promise<string> {
    const rs = this.getRedisConnection();
    return new Promise<string>((resolve, reject): void => {
      rs.create(
        {
          app: 'test',
          id: userId,
          ip: ipAddress,
          ttl: 3600,
          d: {
            data: userData,
          },
        },
        (err: object, resp: { token: string }): void => {
          if (resp !== undefined && resp.token.length > 0) {
            return resolve(resp.token);
          }

          if (err != null) {
            reject(err);
          }
        }
      );
    });
  }

  static getRedisConnection() {
    return new RedisSessions({ host: '127.0.0.1', port: '6379', namespace: 'rs' });
  }
}

index.test.ts

import { RedisSession } from './';

describe('67220364', () => {
  it('should create redis connection', async () => {
    const mRs = {
      create: jest.fn().mockImplementationOnce((option, callback) => {
        callback(null, { token: '123' });
      }),
    };
    const getRedisConnectionSpy = jest.spyOn(RedisSession, 'getRedisConnection').mockReturnValueOnce(mRs);
    const actual = await RedisSession.createSession('teresa teng', '1');
    expect(actual).toEqual('123');
    expect(getRedisConnectionSpy).toBeCalledTimes(1);
    expect(mRs.create).toBeCalledWith(
      {
        app: 'test',
        id: '1',
        ip: 'NA',
        ttl: 3600,
        d: {
          data: 'teresa teng',
        },
      },
      expect.any(Function)
    );
  });
});

单元测试结果:

 PASS  examples/67220364/index.test.ts (8.636 s)
  67220364
    ✓ should create redis connection (5 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |      70 |    57.14 |      75 |      70 |                   
 index.ts |      70 |    57.14 |      75 |      70 | 24-33             
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.941 s