David Gershtenkoren
David Gershtenkoren

Reputation: 111

Jest - How to mock aws-sdk sqs.receiveMessage methode

I try mocking sqs.receiveMessage function which imported from aws-sdk.

Here is my code(sqsHelper.js):

const AWS = require("aws-sdk");

export default class SqsHelper {


  static SqsGetMessagesTest = () => {

    const sqs = new AWS.SQS({
      apiVersion: serviceConfig.sqs.api_version,
      region: serviceConfig.sqs.region,
    });

    const queueURL =
      "https://sqs.us-west-2.amazonaws.com/<1234>/<4567>";

    const params = {
      AttributeNames: ["SentTimestamp"],
      MaxNumberOfMessages: 10,
      MessageAttributeNames: ["All"],
      QueueUrl: queueURL,
      VisibilityTimeout: 20,
      WaitTimeSeconds: 20,
    };


    return new Promise((resolve, reject) => {
      sqs.receiveMessage(params, async (recErr, recData) => {
        if (recErr) {
          reject(recErr);
        } else if (recData.Messages) {
          console.info(`Message count: ${recData.Messages.length}`);
          resolve(recData.Messages);
        }
      });
    });
  };
}

And here is the test file(sqsHelper.test.js):

import SqsHelper from "../../helpers/sqsHelper.js";
import { SQS } from "aws-sdk";

const dumyData = { Messages: [{ name: "123", lastName: "456" }] };
const sqs = new SQS();


describe("Test SQS helper", () => {

  test("Recieve message", async () => {

    jest.spyOn(sqs, 'receiveMessage').mockReturnValue(dumyData);

    // check 1
    const res1 = await sqs.receiveMessage();
    console.log(`res: ${JSON.stringify(res1, null, 2)}`)
    expect(res1).toEqual(dumyData);

    // check 2
    const res2 = await SqsHelper.SqsGetMessagesTest();
    console.log(`res2: ${JSON.stringify(res2, null, 2)}`);
    expect(res2).toBe(dumyData);

  });
});

The problem is that on the first check( which i call the function directly from the test file) i can see that the receiveMessage has been mocked and the results is as expected.

But on the second check(which the function called from the second module "sqsHelper.js") looks that the mock function doe's work and the originalreceiveMessage has been called and it still ask me about credentials.

This is the error:

InvalidClientTokenId: The security token included in the request is
invalid.

what I'm doing wrong?

Thanks

Upvotes: 0

Views: 1589

Answers (1)

Marek Rozmus
Marek Rozmus

Reputation: 958

The receiveMessage should trigger a callback that comes in the params. receiveMessage does not return a Promise Try something like this:

const dummyData = { Messages: [{ name: "123", lastName: "456" }] };

const mockReceiveMessage = jest.fn().mockImplementation((params, callback) => callback("", dummyData));

jest.mock("aws-sdk", () => {
  const originalModule = jest.requireActual("aws-sdk");

  return {
    ...originalModule,
    SQS: function() { // needs to be function as it will be used as constructor
      return {
        receiveMessage: mockReceiveMessage
      }
    }
  };
})

describe("Test SQS helper", () => {
  test("Recieve message", async () => {
    const res = await SqsHelper.SqsGetMessagesTest();
    expect(res).toBe(dummyData.Messages);
  });

  test("Error response", async () => {
    mockReceiveMessage.mockImplementation((params, callback) => callback("some error"));
    await expect(SqsHelper.SqsGetMessagesTest()).rejects.toEqual("some error");
  });
});

Upvotes: 1

Related Questions