Tuesday, May 14, 2024
 Popular · Latest · Hot · Upcoming
54
rated 0 times [  56] [ 2]  / answers: 1 / hits: 13102  / 4 Years ago, sat, april 11, 2020, 12:00:00

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.


More From » node.js

 Answers
13

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


[#4197] Wednesday, April 8, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckenna

Total Points: 445
Total Questions: 109
Total Answers: 109

Location: Virgin Islands (U.S.)
Member since Sun, May 16, 2021
3 Years ago
;