knee-cola / jest-mock-axios

Axios mock for Jest
252 stars 42 forks source link

Question: Using jest-mock-axios with async / await #28

Closed bierik closed 5 years ago

bierik commented 5 years ago

Hei there I have the following question:

My test looks like this:

import AddMeetingModal from '@/components/meeting/AddMeetingModal.vue';
import mockAxios from 'jest-mock-axios';

afterEach(() => { mockAxios.reset(); });

describe('Add Meeting Modal', () => {
  test('current date is passed to the backend when submitting', async (done) => {
    freezeTime(new Date('2018-01-01T07:30'));

    const modal = await localShallow(AddMeetingModal);
    modal.setData({ show: true });

    modal.vm.submit().then(() => {
      expect(modal.vm.show).toBe(false);
      done(); // How can I get rid of this
    });

    mockAxios.mockResponse({ data: { id: 1, title: 'Regierungssitzung vom 11.10.2018' } });
    expect(mockAxios.post.mock.calls[0][1].begin).toEqual('2018-01-01T07:30:00.000Z');
  });
});

As you can see I rely on the done in the callback of the submit method of the component. The show property is set to true when the submit is finished.

So how do I do the same with await, because the then is a bit ugly in my opinion and makes the code more complicated?

When I await the submit, it never resolves because of the missing mockResponse. When I do the mockResponse before the submit, I get No request to respond to!.

Do you have any idea?

kingjan1999 commented 5 years ago

Hi,

Thanks for your interest in this library! I think something along this pattern should work for you (at least it does for me...):

it('can handle async / await stuff', async () => {
    // call an async method which calls axios.post and returns the result
    const promise = makeRequest("post");

    mockAxios.mockResponse({data: 'test'});

    const result = await promise;
    expect(result).toEqual('test');
    expect(mockAxios.post).toHaveBeenCalled();
})

So you should be able to rewrite your code as:

describe('Add Meeting Modal', () => {
  test('current date is passed to the backend when submitting', async () => {
    freezeTime(new Date('2018-01-01T07:30'));

    const modal = await localShallow(AddMeetingModal);
    modal.setData({ show: true });

    const modalSubmitPromise = modal.vm.submit();

    mockAxios.mockResponse({ data: { id: 1, title: 'Regierungssitzung vom 11.10.2018' } });

    await modalSubmitPromise;
    expect(mockAxios.post.mock.calls[0][1].begin).toEqual('2018-01-01T07:30:00.000Z');
    expect(modal.vm.show).toBe(false),
  });
});

I can't test this of course, so please try this (or something similar) and report back.

bierik commented 5 years ago

@kingjan1999 Sorry for the late feedback. Your pattern worked perfectly thank you very much.

MichaelKim39 commented 4 years ago

Thank you! That was extremely helpful, may be worth adding to the readme

kingjan1999 commented 4 years ago

Thank you for the suggestion @MichaelKim39! I've added a simple example (a13ddd9)