如何在单元测试之前等待组件的挂载回调中的异步调用完成?

Posted

技术标签:

【中文标题】如何在单元测试之前等待组件的挂载回调中的异步调用完成?【英文标题】:How to wait for an async call to finish in component's mount callback before unit testing it? 【发布时间】:2021-01-07 16:46:55 【问题描述】:

我正在使用 Jest 对在其 mounted() 方法中进行 Axios 调用的组件进行单元测试。我正在模拟 Axios 调用,因此它返回一个承诺,因此实际上并未进行 API 调用。但问题似乎是因为 Axios 是异步的,我如何告诉我的测试等待 Axios 调用(即使是假的)完成,然后再运行我的期望?

这不起作用:

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');
);

如果我在超时中包装它,它确实有效。我想我读过这篇文章是因为在解决承诺后总是会调用超时或其他什么?

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);
);

有没有更好的方法来做到这一点?

谢谢!

【问题讨论】:

【参考方案1】:

未经测试,但以下方法不起作用吗?

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');
);

(你需要添加https://www.npmjs.com/package/flush-promises(或者你自己写,大概4行代码,返回一个resolved的promise)

【讨论】:

在 vue test utils 文档中发现这一点后,我刚回到这里回答我自己的问题。谢谢,这行得通,正是我所需要的。

以上是关于如何在单元测试之前等待组件的挂载回调中的异步调用完成?的主要内容,如果未能解决你的问题,请参考以下文章

异步调用与回调机制

5.1.23 异步调用与回调机制

如何在useEffect(func,[])中使用异步api调用中的setState钩子测试组件

如何在 koa 中发送 HTTP 响应之前等待 url 回调?

如何使用回调在任何函数中调用异步等待方法

如何在koa发送HTTP响应之前等待url回调?