Brian
Brian

Reputation: 7135

How to wait for an async call to finish in component's mount callback before unit testing it?

I'm using Jest to unit test a component that makes an Axios call in it's mounted() method. I'm mocking the Axios call so it returns a promise so the API call is not actually made. But the problem seems to be that because Axios is asynchronous, how do I tell my test to wait for the Axios call (even the fake one) to complete before running my expectations?

This does not work:

it('calls auth api', () => {
    spyOn(axios, 'get').and.callFake(() => Promise.resolve().then(() => authResponse));
    wrapper = shallowMount(App, {
        localVue,
    });
    expect(axios.get).toHaveBeenCalledWith('api/auth');
    // The "status" data is set in the axios callback. But this fails.
    expect(wrapper.vm.status).toBe('AUTHORIZED');
});

If I wrap it in a timeout, it does work. I think I've read this is because the timeouts are always called after promises are resolved or something?

it('calls auth api', () => {
    spyOn(axios, 'get').and.callFake(() => Promise.resolve().then(() => authResponse));
    wrapper = shallowMount(App, {
        localVue,
    });
    expect(axios.get).toHaveBeenCalledWith('api/auth');
    setTimeout(() => {
        expect(wrapper.vm.status).toBe('AUTHORIZED');
    }, 0);
});

Is there a better way to do this?

Thanks!

Upvotes: 2

Views: 2301

Answers (1)

webdevetc
webdevetc

Reputation: 46

Untested, but does the following not work?

const flushPromises = require('flush-promises');


it('calls auth api', async () => {
    spyOn(axios, 'get').and.callFake(() => Promise.resolve().then(() => authResponse));
    wrapper = shallowMount(App, {
        localVue,
    });

    await flushPromises(); // <<     

    expect(axios.get).toHaveBeenCalledWith('api/auth');
});

(You will need to add https://www.npmjs.com/package/flush-promises (or write your own, it is about 4 lines of code, returning a resolved promise)

Upvotes: 1

Related Questions