0

I am writing React.js application talking to API server. I have read tons of articles on how to mock these calls and send some fake response from API. I can do testing using @testing-library/react, I can easily mock axios with axios-mock-adapter and test fetch requests using HTTP GET method. But I cannot find anywhere how to make sure that my app, when it sends some POST request, sends correct data to API, i.e. that my app sends json payload with e.g. "id" field, or "name" field set to "abc", or something like this.

I am new to React.js. Please advise how to make tests asserting what the app sends to API. Is it possible?

Let's say that I have a function named doSomething, like below, called with onClick of some button.

const doSomething = async (userId, something) => {
    try {
        await REST_API.post('doSomething', {
            user_id: userId,
            something: something
        });
        return true;
    } catch (error) {
        window.alert(error);
        return false;
    }
};

REST_API above is axios instance.

How can I ensure that the I (or some other developer) didn't make a typo and didn't put "userId" instead of "user_id" in the payload of the request?

YotKay
  • 1,127
  • 1
  • 9
  • 25

2 Answers2

2

If you have to be sure you call correctly the api, I'd use jest as follow:

jest.mock('axios', () => ({
  post: jest.fn(),
}));

describe('test', () => {
  it('doSomething', () => {
    const userId = 123;
    const something = 'abc';
    doSomething(userId, something);
    expect(axios.post).toBeCalledWith(
      'doSomething', {
        user_id: userId,
        something,
      },
    );
  });
});

or if you use instance, define it in another file (axios_instance.js) and using the follow test:

jest.mock('./axios_instance', () => ({
  instance: {
    post: jest.fn(),
  },
}));

describe('test', () => {
  it('doSomething', () => {
    const userId = 123;
    const something = 'abc';
    doSomethingInstance(userId, something);
    expect(instance.post).toBeCalledWith(
      'doSomething', {
        user_id: userId,
        something,
      },
    );
  });
});
Max
  • 1,020
  • 7
  • 13
  • I figured out that when using axios mock adapter it is enough to do like this: ```axiosMock = new MockAdapter(REST_API); axiosMock.onPost('doSomething', { user_id: 'uid1', something: 'blabla' }).reply(200);``` – YotKay Feb 17 '20 at 09:28
  • and then ```expect(axiosMock.history.post.length).toEqual(1);``` – YotKay Feb 17 '20 at 09:47
  • yes you can use it, but with jest.mock you are indipendent from the technology used (if one time you decide to use something different from axios for example) – Max Feb 18 '20 at 07:38
-1

For your need I would use Swagger and its tooling. You would kill three birds with one stone :

That way you have a rock solid Frontend + Backend + Documentation combo ..

Jscti
  • 14,096
  • 4
  • 62
  • 87
  • Good idea. But the question was about how to write tests :-) – YotKay Feb 13 '20 at 13:39
  • I almost only red "How can I ensure that the I (or some other developer) didn't make a typo and didn't put "userId" instead of "user_id" in the payload of the request?" And it answers it :D – Jscti Feb 13 '20 at 13:55