Skip to content

mocking axios in lambda u tests

0

Hi team.

i'm using axios in my lambda function to make an http request to an API GW :

//create axios client
const axiosInstance: AxiosInstance = axios.create({
  baseURL: origin,
  httpsAgent: new https.Agent({
    keepAlive: true,
    timeout: xxxx,
  }),
  timeout: xxxxx,
});
await axiosInstance.post(path, rbody, {
      headers: {
        "Content-type": "application/json",
        Authorization: `Bearer ${token}`,
      },
    });

i want to unit test my lambda function by mocking axios call, i tryed many many ways but non of them did not work, i even used npm axios-mock-adapter

import axios, { AxiosInstance } from "axios";
import { handler } from "./mylambda";
import MockAdapter from "axios-mock-adapter";
//https://stackoverflow.com/questions/45016033/how-do-i-test-axios-in-jest
//https://stackoverflow.com/questions/60410731/how-to-mock-interceptors-when-using-jest-mockaxios/60413756#60413756
//https://github.com/lnolazco/hutoma-test/blob/master/src/services/chatbot.test.js
//jest.mock("axios");
//let mockAxios: any = jest.genMockFromModule("axios");

describe("test service", () => {
  let axiosInstance: AxiosInstance;
  beforeEach(() => {
      axiosInstance = {
      post: jest.fn().mockResolvedValue({
        status: 200,
        data: { message: "success" },
      }),
    } as unknown as AxiosInstance;

    // Mock axios.create to return the mock axios instance
    (axios.create as jest.Mock).mockImplementation((config) => axios);
    let requestCallback = () => {
      console.log("There were no interceptors");
    };
    (axios.interceptors.request.use as jest.Mock).mockImplementation(
      (callback) => {
        requestCallback = callback;
      }
    );
    (axios.post as jest.Mock).mockImplementation(() => {
      requestCallback();
      return {
        data: "this is some data",
      };
    });

    //mockAxios.create = jest.fn(() => mockAxios);

    /*axiosInstance = {
      post: jest.fn(),
    } as unknown as AxiosInstance;
    // Mock axios.create to return the axiosInstance object
    //(axios.create as jest.Mock).mockReturnValue(axiosInstance);

    /*(axios.create as jest.Mock).mockReturnValue({
      post: jest
        .fn()
        .mockResolvedValue({ data: {}, status: 200, statusText: "OK" }),
    });*/
    /*axios.post = jest
      .fn()
      .mockResolvedValue({ data: {}, status: 200, statusText: "OK" });*/

    /*const mockResponse = {
      status: 200,
      data: { message: "success" },
    };
     (axiosInstance.post as jest.Mock).mockResolvedValue(mockResponse);*/
    /*(axiosInstance.post as jest.Mock).mockResolvedValue({
      status: 200,
      data: { message: "OK" },  
    });*/
  });

  it("should mock axios instance.post", async () => {
    // Mock the axiosInstance.post method to resolve with mockResponse
    /*mockAxios.post.mockImplementationOnce(() =>
      Promise.resolve({ data: {}, status: 200, statusText: "OK" })
    );
    /*(axiosInstance.post as jest.Mock)
      .mockResolvedValue({
        data: {},
        status: 200,
        statusText: "OKFromTEST",
      });*/
    /*var mock = new MockAdapter(axios);
    const data = { response: true };
    mock.onPost(url).reply(200, data);*/

    await handler(event);
 
  });
});

so my test fail because some times it try to call the mock url and it timed out and sometimes because the mock did not work properly i already mocked axios.create that return an AxiosInstance

any help please how to mock axiosInstance.post ?

so this part of my lambda function did not fail on tests :

//create axios client
const axiosInstance: AxiosInstance = axios.create({
  baseURL: origin,
  httpsAgent: new https.Agent({
    keepAlive: true,
    timeout: xxxx,
  }),
  timeout: xxxxx,
});
await axiosInstance.post(path, rbody, {
      headers: {
        "Content-type": "application/json",
        Authorization: `Bearer ${token}`,
      },
    });
2 Answers
0

For implementing above scenario you can use a dedicated mocking library like axios-mock-adapter used for testing applications that use the axios HTTP client library in below format as mentioned in the example:

  1. Import axios-mock-adapter and create a new instance, passing the axios module as an argument.
  2. Use the onPost method to define the mock response for the specific URL or request body.

Here's an example:

import MockAdapter from 'axios-mock-adapter';

describe('test service', () => {
  let mock;

  beforeEach(() => {
    mock = new MockAdapter(axios);
    mock.onPost(path).reply(200, { message: 'success' });
  });

  afterEach(() => {
    mock.restore();
  });

  it('should mock axios instance.post', async () => {
    await handler(event);
    expect(mock.history.post[0].headers).toEqual(
      expect.objectContaining({
        'Content-type': 'application/json',
        Authorization: expect.stringMatching(/^Bearer .+$/),
      })
    );
  });
});

This approach uses axios-mock-adapter to intercept the axios.post call and define the mock response. The onPost method is used to specify the mock response for the specific request.

AWS
answered a year ago
-1

To effectively mock the axios instance in your Lambda function unit tests, you can use Jest's mocking capabilities. Here's an approach you can try:

  1. First, mock the entire axios module:
jest.mock('axios');
  1. In your test setup, create a mock implementation for axios.create:
const mockPost = jest.fn();
const mockAxiosCreate = jest.fn(() => ({
post: mockPost,
}));
(axios.create as jest.Mock).mockImplementation(mockAxiosCreate);
  1. Now you can set up expectations for the post method in your individual tests:
it('should mock axios instance.post', async () => {
mockPost.mockResolvedValueOnce({
status: 200,
data: { message: 'success' },
});

await handler(event);

expect(mockPost).toHaveBeenCalledWith(
expect.any(String),
expect.any(Object),
expect.objectContaining({
headers: expect.objectContaining({
'Content-type': 'application/json',
Authorization: expect.stringMatching(/^Bearer .+$/),
}),
})
);
});

This approach mocks the axios.create method to return an object with a mocked post method. You can then set up expectations for the post method in each test, allowing you to control its behavior and verify it's called correctly.

Remember to reset your mocks between tests if necessary:

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

This method should prevent timeouts by ensuring that no real HTTP requests are made during your tests. It also gives you fine-grained control over the mock responses, allowing you to test different scenarios easily.
Sources
AWS Lambda function testing in C# - AWS Lambda

answered a year ago
  • this did not work in my lambda axiosInstance end up with 'undefined' value

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.