如何测试异步等待与jest的pg连接?

时间:2017-09-11 09:13:26

标签: javascript async-await pg jest

我正在尝试使用async await,

来测试与pg建立连接的函数

import pg from 'pg';

module.exports.test = async(event, context, callback) => {

  const client = new pg.Client(someConnectionString);
  try {
    await client.connect();
  } catch (e) {
    return callback(e);
  }
  try {
    await client.query(await someAsyncFunction(test));
    client.end();
    return callback(null, 'success');
  } catch (e) {
    client.end();
    return callback(e);
  }

真的不明白我会如何使用jest来嘲笑这个?有什么想法吗?

2 个答案:

答案 0 :(得分:0)

首先,开个玩笑,您可以返回一个承诺来测试异步代码:

import pg from 'pg';

module.exports.test = async (event, context) => {
  const client = new pg.Client(someConnectionString);
  try {
    await client.connect();
    await client.query(await someAsyncFunction(test));
  } finally {
    client.end();
  }
};

由于任何async函数都会返回一个承诺,因此您不必手动将错误传递给回调。

现在有了关于如何模拟pg的问题,您可以创建一个伪造的pg对象,但这并不是很理想,我只展示一个示例来回答实际问题。

您应该尝试在运行测试之前设置测试数据库,然后再进行清理,这样您就不必模拟任何东西,并且可以使用真正的pg来提高质量测试。

// mock example:
class MockClient {
  async connect() {
  }
  async query() {
  }
}

答案 1 :(得分:0)

这是单元测试解决方案:

index.js

import pg from 'pg';
import { someAsyncFunction } from './someAsyncFunction';

const someConnectionString = 'someConnectionString';
const test = 'test';

module.exports = async (event, context, callback) => {
  const client = new pg.Client(someConnectionString);
  try {
    await client.connect();
  } catch (e) {
    return callback(e);
  }
  try {
    await client.query(await someAsyncFunction(test));
    client.end();
    return callback(null, 'success');
  } catch (e) {
    client.end();
    return callback(e);
  }
};

someAsyncFunction.js

export async function someAsyncFunction() {}

index.test.js

import pg from 'pg';
import fn from './';
import { someAsyncFunction } from './someAsyncFunction';

jest.mock('./someAsyncFunction', () => {
  return { someAsyncFunction: jest.fn() };
});
jest.mock('pg', () => {
  const mClient = { connect: jest.fn(), query: jest.fn(), end: jest.fn() };
  return { Client: jest.fn(() => mClient) };
});

describe('46152048', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should query success', async (done) => {
    someAsyncFunction.mockResolvedValueOnce('select 1;');
    const mClient = new pg.Client();
    mClient.connect.mockResolvedValueOnce();
    await fn({}, {}, (err, result) => {
      expect(pg.Client).toBeCalledWith('someConnectionString');
      expect(someAsyncFunction).toBeCalledWith('test');
      expect(mClient.query).toBeCalledWith('select 1;');
      expect(mClient.end).toBeCalledTimes(1);
      expect(err).toBeNull();
      expect(result).toBe('success');
      done();
    });
  });

  it('should handle error if connect database failed', async () => {
    const mError = new Error('network');
    const mClient = new pg.Client();
    mClient.connect.mockRejectedValueOnce(mError);
    await fn({}, {}, (err, result) => {
      expect(err.message).toBe('network');
      expect(result).toBeUndefined();
    });
  });

  it('should handle error if query failed', async () => {
    const mError = new Error('network');
    const mClient = new pg.Client();
    mClient.connect.mockResolvedValueOnce();
    mClient.query.mockRejectedValueOnce(mError);
    await fn({}, {}, (err, result) => {
      expect(err.message).toBe('network');
      expect(mClient.end).toBeCalledTimes(1);
      expect(result).toBeUndefined();
    });
  });
});

具有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/46152048/index.test.js
  46152048
    ✓ should query success (11ms)
    ✓ should handle error if connect database failed (1ms)
    ✓ should handle error if query failed (1ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.js |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.103s, estimated 10s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/46152048