Vue3:测试onMounted钩子中异步函数内的加载状态失败
解决Vue组件onMounted加载状态测试问题
问题出在Vue的异步DOM更新机制上。当你在onMounted钩子中设置isLoading.value = true时,Vue并不会立刻更新DOM——状态变更会被推入微任务队列,等待当前同步代码执行完成后才会处理。你的测试在组件mount之后立刻断言loading元素存在,此时DOM还没完成更新,组件依然处于初始状态(isLoading还是初始的false,collections为空),所以显示的是EmptyCollection组件。
修正后的测试代码
it('renders "Loading..." while data is fetching, then shows EmptyCollection when data is empty', async () => { // Mock empty collection response (getCollectionList as jest.Mock).mockResolvedValueOnce({}); const wrapper = mount(MyCollections, wrapperOptions); // 等待Vue处理isLoading状态变更后的DOM更新 await nextTick(); // 此时loading状态已经渲染到DOM中 expect(wrapper.find('[data-test="loadingCollections"]').exists()).toBe(true); // 等待onMounted中的异步请求完成 await flushPromises(); // 请求完成后,loading消失,EmptyCollection显示 expect(wrapper.find('[data-test="loadingCollections"]').exists()).toBe(false); expect(wrapper.find('[data-test="emptyCollectionWrapper"]').exists()).toBe(true); expect(wrapper.find('[data-test="collectionCards"]').exists()).toBe(false); });
关键步骤解释
await nextTick():这一步是让测试等待Vue完成状态变更后的DOM更新。当你设置isLoading.value = true后,Vue需要一点时间把这个状态反映到DOM上,nextTick()会等待这个过程完成。await flushPromises():这一步是等待onMounted中的getCollectionList异步请求完成,以及后续的状态变更(collections赋值、isLoading设为false)和对应的DOM更新。
另外,确认你的isLoading初始值是ref(false)——如果初始值设为true,虽然也能显示loading,但不符合真实的加载流程(应该是开始请求时才设为true)。
内容的提问来源于stack exchange,提问作者Lazouski
相关产品推荐
相关产品推荐

