DEV Community

Cover image for How to mock the aws-sdk?
Lucas Ferreira
Lucas Ferreira

Posted on

How to mock the aws-sdk?

Class to be tested

import { Lambda } from 'aws-sdk';

export default class Service {
    public async callLambda(): Promise<void> {
        const lambda = new Lambda();
        const params: Lambda.Types.InvocationRequest = {
            FunctionName: `function-name`,
            InvocationType: 'Event',
        };
        await lambda.invoke(params).promise();
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Let suppose that we have a service that call a lambda using the aws-sdk library.
  • aws-sdk version: 2.546.0.

Unit test with the mock

First way

import Service from '../../../../src/api/services/Service';

const fakePromise = {
    promise: jest.fn(),
};

jest.mock('aws-sdk', () => ({
    Lambda: jest.fn(() => ({
        invoke: () => fakePromise,
    })),
}));

describe('callLambda', () => {

    it('should return something... ', async done => {
        const service = new Service();
        const result = await service.callLambda();
        expect(result).toBeUndefined();
        done();
    });

    it('should throw an error... ', async done => {
        // modifying the implementation before call the function
        fakePromise.promise = jest.fn()
            .mockImplementation(() => Promise.reject(new Error()));

        try {
            const service = new Service();
            const result = await service.callLambda();
            expect(result).toBeUndefined();
        } catch (error) {
            expect(error).toBeDefined();
        }
        done();
    });
});
Enter fullscreen mode Exit fullscreen mode

Second way

import { Lambda } from 'aws-sdk';
import Service from '../../../../src/api/services/Service';

// removing the factory function of the first way
jest.mock('aws-sdk');

describe('callLambda', () => {
    // moving the fake to inside our describe test
    // because we don't need it in jest.mock
    const fakePromise = {
        promise: jest.fn(),
    };

    beforeEach(() => {
        // adding the implementation before each test
        (Lambda as any).mockImplementation(() => {
            return {
                invoke: () => fakePromise,
            };
        });
    });

    it('should return something... ', async done => {
        const service = new Service();
        const result = await service.callLambda();
        expect(result).toBeUndefined();
        done();
    });

    it('should throw an error... ', async done => {
        // modifying the implementation before call the function
        fakePromise.promise = jest.fn()
            .mockImplementation(() => Promise.reject(new Error()));

        try {
            const service = new Service();
            const result = await service.callLambda();
            expect(result).toBeUndefined();
        } catch (error) {
            expect(error).toBeDefined();
        }
        done();
    });
});
Enter fullscreen mode Exit fullscreen mode
  • Inside the unit tests we can just change the fakePromise or update the mockImplementation to pretend the behaviors that we need.
  • We can use these approaches to create unit test for other classes inside the aws-sdk.
  • jest version: 24.9.0.

Conclusion

The most difficult part of writing unit test is creating the mocks for external libraries, the purpose of this article is just help someone with troubles to mock this kind of library. We have a lot of ways to mock libraries, feel free to comment and send suggestions.

Discussion (0)