How to mock an axios request using sinon modules
Asked Answered
D

2

13

There seems to be so many different ways to do this, but I am trying to use just sinon, sinon-test, chai/mocha, axios, httpmock modules. I am not able to successfully mock a GET call made using axios. I want to be able to mock the response from that axios call so the unit test won't actually have to make the external API request.

I've tried setting up a basic unit test by creating a sandbox, and using sinon stub to set up a GET call and specify the expected response. I'm unfamiliar with JavaScript and NodeJS.

// Main class (filename: info.js)

function GetInfo(req, res) {
    axios.get(<url>).then(z => res.send(z.data));
}

// Test class (filename: info.test.js)

it ("should return info", () => {
    const expectedResponse = "hello!";
    const res = sinon.spy();
    const aStub = sinon.stub(axios, "get").resolves(Promise.resolve(expectedResponse));

    const req = httpMock.createRequest({method:"get", url:"/GetInfo"});

    info.GetInfo(req, res);

    // At this point, I need to evaluate the response received (which should be expectedResponse)
    assert(res.data, expectedResponse); // data is undefined, res.status is also undefined

    // How do I read the response received?

});

I need to know how to read the response that is supposed to be sent back (if it is being captured in the first place by sinon).

Duralumin answered 4/7, 2019 at 5:12 Comment(0)
U
6

I'm assuming the response you're wanting to check is the z.data being passed to res.send(z.data)

I don't think your Sinon Spy is being set up correctly.

In your example, res is a function created by sinon. This function won't have a property data.

You probably want to create a spy like this:

const res = {
  send: sinon.spy()
}

This gives you a res object which has a spy with the key send. You can then make assertions about the parameters used to call res.send

it ("should return info", () => {
    const expectedResponse = "hello!";
    const res = {
      send: sinon.spy()
    };
    const aStub = sinon.stub(axios, "get").resolves(Promise.resolve(expectedResponse));

    const req = httpMock.createRequest({method:"get", url:"/GetInfo"});

    info.GetInfo(req, res);

    // At this point, I need to evaluate the response received (which should be expectedResponse)
    assert(res.send.calledWith(expectedResponse)); // data is undefined, res.status is also undefined

});
Unspoiled answered 4/7, 2019 at 6:34 Comment(1)
Thanks for your response. For some reason the asserts against res.send fail for me. Res.send is not called at all, I wanted to verify that calledOnce = true.Duralumin
C
2

Dont know if this helps but you may not be getting the correct response because resolves is a return with a promise wrap over it.

So by using resolves and inside it a Promise.resolve you are actually returning Promise wrap in a Promise.

Maybe you can try changing the code to the one below.

const aStub = sinon.stub(axios, "get").resolves(Promise.resolve(expectedResponse));

to

const aStub = sinon.stub(axios, "get").resolves(expectedResponse);
Crosslegged answered 9/7, 2021 at 6:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.