javascript - 开玩笑模拟 aws-sdk ReferenceError:在初始化之前无法访问
问题描述
开玩笑 25.3.0
我试图在我的单元测试中模拟 DynamoDB 依赖项,如下所示:
const { findById } = require('./mymodule');
const mockDynamoDB = { getItem: jest.fn() };
jest.mock('aws-sdk', () => ({
DynamoDB: jest.fn(() => mockDynamoDB)
}));
describe('.', () => {
it('..', () => {
findById('test');
expect(mockDynamoDB.getItem).toBeCalledWith({
TableName: 'table-name',
Key: {
id: { S: 'test' }
}
});
});
});
不幸的是,当我这样做时,我收到以下错误:
ReferenceError: Cannot access 'mockDynamoDB' before initialization
奇怪的是,如果我这样做,我可以避免ReferenceError
:
const mockGetItem = { promise: jest.fn() };
jest.mock('aws-sdk', () => ({
DynamoDB: jest.fn(() => ({
getItem: jest.fn(() => mockGetItem)
})
}));
但这不适合我的测试,因为我无法验证传递给getItem
函数的参数。
实际测试的代码相当简单,看起来像这样:
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
const toRecord = (item) => ({
id: item.id.S,
name: item.name.S
});
const findById = (id) => (
dynamodb.getItem({
TableName: 'table-name',
Key: {
id: { S: id }
}
}).promise()
.then(result => toRecord(result.Item))
.catch(error => console.log(error)
);
module.exports = {
findById
}
如果有人以前见过这个,或者可以阐明为什么第一个示例失败而第二个有效,它真的会帮助我。谢谢你。
解决方案
这是单元测试解决方案:
index.js
:
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
const toRecord = (item) => ({
id: item.id.S,
name: item.name.S,
});
const findById = (id) =>
dynamodb
.getItem({
TableName: 'table-name',
Key: {
id: { S: id },
},
})
.promise()
.then((result) => toRecord(result.Item))
.catch((error) => console.log(error));
module.exports = { findById };
index.test.js
:
const { findById } = require('./');
const AWS = require('aws-sdk');
jest.mock('aws-sdk', () => {
const mDynamoDB = { getItem: jest.fn().mockReturnThis(), promise: jest.fn() };
return { DynamoDB: jest.fn(() => mDynamoDB) };
});
describe('61157392', () => {
let dynamodb;
beforeAll(() => {
dynamodb = new AWS.DynamoDB();
});
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', async () => {
dynamodb.getItem().promise.mockResolvedValueOnce({
Item: {
id: { S: '1' },
name: { S: 'a' },
},
});
const actual = await findById('1');
expect(actual).toEqual({ id: '1', name: 'a' });
expect(dynamodb.getItem).toBeCalledWith({
TableName: 'table-name',
Key: {
id: { S: '1' },
},
});
expect(dynamodb.getItem().promise).toBeCalledTimes(1);
});
});
覆盖率 100% 的单元测试结果:
PASS stackoverflow/61157392/index.test.js (8.216s)
61157392
✓ should pass (4ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 88.89 | 100 | 75 | 87.5 |
index.js | 88.89 | 100 | 75 | 87.5 | 19
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 9.559s
源代码:https ://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61157392
推荐阅读
- java - 从 Spring 4.x 升级到 5.x 时出现“InvalidPathException: Illegal char <*>”
- php - assertContains() url:测试最佳实践
- bitcoin - Libra 加密交易 - 你如何真正跟踪交易?
- java - 如果名称相等,我如何在java帮助中删除重复的这个jsonarray需要合并部门列表,否则设置为单独的json对象
- laravel - 如何关闭我们服务器(cpanel)上的 smtp 或数据库端口?
- javascript - 在 WordPress 中 ajax 调用多种表单的最佳实践
- r - 我想查看日期的频率,因为它们显示为一周中的几天以及每小时
- java - Spring Boot - 返回带有对象数组的 JSON
- php - 文件目录和下载文件 URL 错误
- java - 查询之间的mongo jpa