Search code examples
javascriptmocha.jschaisinonaws-sdk-js

Stubing AWS SQS client


Im trying to stub aws-sdk/client-sqs calls. Im both new to aws and stubbing and I cant find much in the docs to do with stubbing using mocha/chai

My file

import { SQSClient, ReceiveMessageCommand, DeleteMessageCommand } from '@aws-sdk/client-sqs'
const sqsClient = new SQSClient()

const params = {
    AttributeNames: ['SentTimestamp'],
    MaxNumberOfMessages: 10,
    QueueUrl: paymentsUrl,
    //....more params
}

const getPolledMessages = async sqsClient => {

    const data = await sqsClient.send(new ReceiveMessageCommand(params))
    //....continue to do stuff with the data
}

My test is as below. I heavily borrowed from this test which stubs @aws-sdk/client-ses

import { ReceiveMessageCommand, SQSClient } from '@aws-sdk/client-sqs'
import { expect } from 'chai'


describe('mock sqs', () => {
  let stub;
  before(() => {
    stub = sinon.stub(SQSClient.prototype, 'ReceiveMessageCommand')
  })
  after(() => stub.restore())

  it('can send', async () => {
    await SQSClient.send(new ReceiveMessageCommand(params))
    expect(stub.calledOnce).to.be.true
  })
})

Currently getting the following error

 TypeError: Cannot stub non-existent property ReceiveMessageCommand
 at Function.stub (node_modules/sinon/lib/sinon/stub.js:73:15)
 at Sandbox.stub (node_modules/sinon/lib/sinon/sandbox.js:333:37)

Solution

  • You can stub out dependencies with link seams.. We should use proxyquire package to do that.

    E.g.

    index.ts:

    import { SQSClient, ReceiveMessageCommand } from '@aws-sdk/client-sqs';
    const sqsClient = new SQSClient({ region: 'REGION' });
    
    const params = {
      AttributeNames: ['SentTimestamp'],
      MaxNumberOfMessages: 10,
      QueueUrl: 'paymentsUrl',
    };
    
    export const getPolledMessages = async () => {
      const data = await sqsClient.send(new ReceiveMessageCommand(params));
    };
    

    index.test.ts:

    import proxyquire from 'proxyquire';
    import sinon from 'sinon';
    
    describe('68017252', () => {
      it('should pass', async () => {
        const sqsClientInstance = {
          send: sinon.stub(),
        };
        const SQSClient = sinon.stub().returns(sqsClientInstance);
        const ReceiveMessageCommand = sinon.stub();
        const { getPolledMessages } = proxyquire('./', {
          '@aws-sdk/client-sqs': {
            SQSClient,
            ReceiveMessageCommand,
          },
        });
        await getPolledMessages();
        sinon.assert.calledWithExactly(SQSClient, { region: 'REGION' });
        sinon.assert.calledOnce(sqsClientInstance.send);
        sinon.assert.calledWithExactly(ReceiveMessageCommand, {
          AttributeNames: ['SentTimestamp'],
          MaxNumberOfMessages: 10,
          QueueUrl: 'paymentsUrl',
        });
      });
    });
    

    test result:

      68017252
        ✓ should pass (3331ms)
    
    
      1 passing (3s)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |     100 |      100 |     100 |     100 |                   
     index.ts |     100 |      100 |     100 |     100 |                   
    ----------|---------|----------|---------|---------|-------------------