16

I am using https://github.com/ctimmerm/axios-mock-adapter

I would like to know how can I verify that an endpoint was actually called by the system under test.

In this example:

var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');

// This sets the mock adapter on the default instance
var mock = new MockAdapter(axios);

// Mock any GET request to /users
// arguments for reply are (status, data, headers)
mock.onGet('/users').reply(200, {
  users: [
    { id: 1, name: 'John Smith' }
  ]
});

How could I tell if a get on '/users' was called?

I am looking for something similar to what you can do in Jest:

expect(mockFunc).toHaveBeenCalledTimes(1)

I realise I can use some custom logic when using a function to reply, and setting a local variable indicating if the request has been made. I was just wondering if there was a cleaner way of doing this.

Daryn
  • 2,493
  • 4
  • 26
  • 38

3 Answers3

17

axios-mock-adapter does not appear to have this functionality built in to it, however if you are using jest, you can use jest.spyOn.

For your example above

let spy = jest.spyOn(axios, "get");
//run http request here
expect(spy).toHaveBeenCalled();

Note: depending on what you are using, you may have to wrap your expect statement in setTimeout(function, 0) for it to work properly

Perogy
  • 304
  • 3
  • 7
  • 2
    Is there a way to spy on particular URL? I have multiple gets in one function and I want to verify each of them. – Black Aug 07 '18 at 10:30
  • 3
    It is possible to change toHaveBeenCalled into toHaveBeenCalledWith. eg.: expect(spy).toHaveBeenCalledWith('/users'); – Black Aug 07 '18 at 14:53
  • 2
    Yep that's exactly how I would do it. Note that if you were doing a post instead of a get, you'd also have the payload parameter. In this case if you don't care about verifying the payload data that was sent you could do expect(spy).toHaveBeenCalledWith('/users', expect.anything()); to just verify the address – Perogy Aug 07 '18 at 17:58
  • It workes, but when i run second test, the toHaveCalledTimes returns 2, somehow its not clearning the old call. – Sarmad Shah Nov 25 '19 at 11:16
  • @SarmadShah Try running jest.clearAllMocks() after each test – Perogy Dec 12 '19 at 17:30
4

Another alternative is to do

//OP's Code
var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');

// This sets the mock adapter on the default instance
var mock = new MockAdapter(axios);

// Mock any GET request to /users
// arguments for reply are (status, data, headers)
mock.onGet('/users').reply(200, {
  users: [
    { id: 1, name: 'John Smith' }
  ]
});

const spy = jest.spyOn(mock, 'onGet');

//function call here

expect(spy).toHaveBeenCalledWith('/users')

Essentially since the Mock "intercepts" axios calls you can't test for an axios.get call.. because it never actually happens. But the mock.onGet function does get executed and you can verify what route was used to do it as well.

Trying to spy on axios when you're mocking it will get you an error looking like this

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: "/users"

Number of calls: 0

Cheers.

search-learn
  • 427
  • 2
  • 13
2

As per https://github.com/ctimmerm/axios-mock-adapter there is an out of the box functionality for verifying request calls:

expect(mock.history.post.length).toBe(1); // times called
expect(mock.history.post[0].data).toBe(JSON.stringify({ foo: "bar" })); // posted object
Laszlo Sarvold
  • 328
  • 2
  • 11