我正在尝试使用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来嘲笑这个?有什么想法吗?
答案 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