Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock AWS DynamoDB in Jest for Serverless Nodejs Lambda?

I wrote a lambda as follows.

handler.js

const aws = require('aws-sdk');
const dynamoDb = new aws.DynamoDB.DocumentClient();

const testHandler = async event => {
  // some code
  // ...
  const user = await getUser(userId)
  // ...
  // some code
}

const promisify = foo => new Promise((resolve, reject) => {
  foo((error, result) => {
    if (error) {
      reject(error)
    } else {
      resolve(result)
    }
  })
})

const getUser = (userId) => promisify(callback =>
  dynamoDb.get({
    TableName: 'test-table',
    Key: {
      "PK": `${userId}`,
      "SK": `${userId}`
    }
  }, callback))
  .then((user) => {
    console.log(`Retrieved user: ${userId}`)
    return user
  })


module.exports = {
  testHandler: testHandler,
  getUser: getUser
}

I want to write a unit test for testing the getUser function so I tried the following.

handler.test.js

const handler = require('../handler');
const AWS = require('aws-sdk')

const dynamoDbGetParameterPromise = jest.fn().mockReturnValue({
  promise: jest.fn().mockResolvedValue({
    PK: 'userId-123', SK: 'userId-123'
  })
})

AWS.DynamoDB.DocumentClient = jest.fn().mockImplementation(() => ({
  get: dynamoDbGetParameterPromise
}))


describe('test getUser', () => {

  beforeEach(() => {
    jest.resetModules()
  });

  test('get user success', async () => {
    const user = { PK: 'userId-123', SK: 'userId-123' };
    const result = await handler.getUser(userId);
    expect(result).toEqual(user);
  });
});

The error is as follows.

ConfigError: Missing region in config

      105 |
      106 | const getUser = (userId) => promisify(callback =>
    > 107 |   dynamoDb.get({
          |            ^
      108 |     TableName: 'test-table',
      109 |     Key: {
      110 |       "PK": 'userId-123',

It seems the test still uses the dynamoDb in the handler.js rather than the mocked in the test.

Any ideas on how to wire up the mock correctly to test the function? Thanks in advance!

like image 549
Conan Avatar asked Apr 25 '26 05:04

Conan


1 Answers

You can use jest's auto-mock by adding

jest.mock("aws-sdk");

and then AWS.DynamoDB.DocumentClient will be a mocked class so you'll be able to mock it's implementation. And since we want it's get method to be a function that accepts anything as a first argument (as we won't do anything with it within the mock implementation) and a callback that we're expecting it to have been called with null and user we can mock it like this:

AWS.DynamoDB.DocumentClient.prototype.get.mockImplementation((_, cb) => {
  cb(null, user);
});
like image 143
Teneff Avatar answered Apr 26 '26 23:04

Teneff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!