[英]TypeError: AWS.DynamoDB.DocumentClient is not a constructor
[英]TypeError: AWS.DynamoDB.DocumentClient is not a constructor when testing with Jest
我正在运行 jest 测试来测试 dynamodb.js 文件和使用 dynamodb.js 文件的 create.js 文件。 create.js 模块是通用的,可以通过构造参数 object 并将其传递到任何表中。 但是,我收到了下面的错误,我需要帮助。
TypeError: AWS.DynamoDB.DocumentClient is not a constructor
__mock__
文件夹
const getMock = jest.fn().mockImplementation(() => {
return {
promise() {
return Promise.resolve({});
}
};
});
const putMock = jest.fn().mockImplementation(() => {
return {
promise() {
return Promise.resolve({});
}
};
});
// eslint-disable-next-line func-names
function DynamoDB() {
return {
DocumentClient: jest.fn(() => ({
get: getMock,
put: putMock
}))
};
}
const AWS = { DynamoDB, getMock, putMock };
module.exports = AWS;
dynamodb.js
const AWS = require('aws-sdk');
const http = require('http');
const https = require('https');
const url = require('url');
module.exports = endpoint => {
const { protocol } = url.parse(endpoint || '');
const agentConfig = {
keepAlive: true,
keepAliveMsecs: 20000
};
const httpOptions =
protocol === 'http:' ? { agent: new http.Agent(agentConfig) } : { agent: new https.Agent(agentConfig) };
const db = new AWS.DynamoDB({
endpoint,
httpOptions
});
const docClient = new AWS.DynamoDB.DocumentClient({
service: db
});
return {
docClient,
db
};
};
dynamodb.spec.js
const AWS = require('aws-sdk');
const dynamodb = require('../../../src/dynamodb');
describe('dynamodb.js', () => {
beforeEach(() => {
// jest.resetModules();
});
test('calls generic-dynamodb-lib dynamodb', async () => {
dynamodb('http://localhost:8001');
expect(AWS.DynamoDB).toHaveBeenCalled();
expect(AWS.DynamoDB.DocumentClient).toHaveBeenCalled();
});
});
创建.js
// Imports here
const create = async (log, docClient, table, tableRecord) => {
try {
await docClient.put({ TableName: table, Item: tableRecord }).promise();
} catch (error) {
log.error({ message: 'DynamoDB error', ...error });
throw Error.internal();
}
return tableRecord;
};
module.exports = create;
我还尝试用 doMock 块替换模拟中的手动模拟,但仍然继续收到上述相同的错误。 一旦我克服了这个问题,考虑到 docClient.js 被传递到 function 中,我该如何测试 create.js? 非常感谢。
DocumentClient
应该是 static 属性,而它被模拟为实例属性。
它应该是:
const DynamoDB = jest.fn().mockReturnValue({});
DynamoDB.DocumentClient = jest.fn().mockReturnValue({
get: getMock,
put: putMock
});
非常感谢您的回复。 在看到这里的响应之前,我已经找到了解决问题的方法。
我最终不需要在__mock__
目录中放置任何模拟。
请参阅我提出的测试:
创建.spec.js
const AWS = require('aws-sdk');
const dynamodb = require('../../../src/dynamodb');
const create = require('../../../src/create');
describe('create.js', () => {
beforeEach(() => {
jest.resetModules();
});
test('calls DocumentClient put with a successful outcome', async () => {
const log = { error: jest.fn() };
const fakePut = jest.fn().mockImplementation(() => {
return {
promise() {
return Promise.resolve({});
}
};
});
AWS.DynamoDB.DocumentClient = jest.fn(() => ({
put: fakePut
}));
const document = {
brands: ['visa', 'mc', 'amex', 'maestro', 'diners', 'discover', 'jcb']
};
const { docClient } = dynamodb('https://localhost:8001');
await create(log, docClient, 'a-table-name', {
countryCode: 'US',
merchantAccount: 'MerchantAccountUS',
expireAt: 1593814944,
document
});
expect(create).toEqual(expect.any(Function));
expect(fakePut).toHaveBeenCalled();
expect(fakePut).toHaveBeenCalledWith({
TableName: 'a-table-name',
Item: {
countryCode: 'US',
merchantAccount: 'MerchantAccountUS',
expireAt: 1593814944,
document
}
});
});
test('calls DocumentClient put with unsuccessful outcome', async () => {
const log = { error: jest.fn() };
const fakePut = jest.fn().mockImplementation(() => {
throw Error.internal();
});
AWS.DynamoDB.DocumentClient = jest.fn(() => ({
put: fakePut
}));
const document = {
brands: ['visa', 'mc', 'amex', 'maestro', 'diners', 'discover', 'jcb']
};
const { docClient } = dynamodb('https://localhost:8001');
let thrownError;
try {
await create(log, docClient, 'a-table-name', {
countryCode: 'US',
merchantAccount: 'MerchantAccountUS',
expireAt: 1593814944,
document
});
} catch (e) {
thrownError = e;
}
expect(create).toEqual(expect.any(Function));
expect(fakePut).toHaveBeenCalled();
expect(fakePut).toHaveBeenCalledWith({
TableName: 'a-table-name',
Item: {
countryCode: 'US',
merchantAccount: 'MerchantAccountUS',
expireAt: 1593814944,
document
}
});
expect(thrownError).toEqual(Error.internal());
});
});
dynamodb.spec.js
const AWS = require('aws-sdk');
const http = require('http');
const https = require('https');
const url = require('url');
const dynamodb = require('../../../src/dynamodb');
const fakeFunction = jest.fn().mockImplementation(() => {});
const FakeDynamoDB = jest.fn(() => ({
DocumentClient: fakeFunction
}));
AWS.DynamoDB = FakeDynamoDB;
const fakeGet = fakeFunction;
const fakePut = fakeFunction;
const FakeDocumentClient = jest.fn(() => ({
get: fakeGet,
put: fakePut
}));
AWS.DynamoDB.DocumentClient = FakeDocumentClient;
describe('dynamodb.js', () => {
beforeEach(() => {
jest.resetModules();
});
test('calls DynamoDB and DocumentClient constructors with http protocol and with endpoint present', () => {
const fakeParse = jest.fn().mockImplementation(() => 'http');
url.parse = fakeParse;
const fakeHttpAgent = jest.fn().mockImplementation(() => {});
http.Agent = fakeHttpAgent;
dynamodb('http://localhost:8001');
expect(FakeDynamoDB).toHaveBeenCalled();
expect(FakeDocumentClient).toHaveBeenCalled();
});
test('calls DynamoDB and DocumentClient constructors with https protocol and with endpoint present', () => {
const fakeParse = jest.fn().mockImplementation(() => 'https');
url.parse = fakeParse;
const fakeHttpsAgent = jest.fn().mockImplementation(() => {});
https.Agent = fakeHttpsAgent;
dynamodb('https://localhost:8001');
expect(FakeDynamoDB).toHaveBeenCalled();
expect(FakeDocumentClient).toHaveBeenCalled();
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.