Jest 25.3.0
I am trying to mock DynamoDB dependency in my unit tests as follows:
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' }
}
});
});
});
Unfortunately, when I do that, I get the following error:
ReferenceError: Cannot access 'mockDynamoDB' before initialization
Strangely, if I do this, I can avoid the ReferenceError
:
const mockGetItem = { promise: jest.fn() };
jest.mock('aws-sdk', () => ({
DynamoDB: jest.fn(() => ({
getItem: jest.fn(() => mockGetItem)
})
}));
but this doesn't suit my test, as I can't validate the params passed to the getItem
function.
The actual code under test is fairly simple, it looks something like this:
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
}
If anyone has seen this before, or can shed some light on why the first example fails while the second works, it would really help me out. Thank you.
Here is the unit test solution:
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);
});
});
unit test results with 100% coverage:
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
source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61157392
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With