Vitest测试报错:如何验证useEffect中调用了asyncThunk
问题原因与解决方法
报错原因
你遇到的TypeError: [Function actionCreator] is not a spy or a call to a spy!错误,是因为fetchCoordinates是Redux Toolkit通过createAsyncThunk生成的action creator函数,并非Vitest的间谍(spy)函数。Vitest无法直接跟踪普通函数的调用次数,必须将目标函数转换为间谍函数后,才能使用toHaveBeenCalledTimes这类断言方法。
解决方案
下面提供两种可行的修改方案,任选其一即可:
方案一:使用vi.mock模块级Mock
直接Mock整个locationSlice模块,将fetchCoordinates替换为间谍函数:
import { describe, it, expect, beforeEach, vi } from 'vitest' import { render } from '@testing-library/react' import { Provider } from 'react-redux' import App from '../App' import store from '../app/store' import * as locationSlice from '../features/location/locationSlice' // Mock整个locationSlice模块,替换fetchCoordinates为间谍函数 vi.mock('../features/location/locationSlice', () => ({ fetchCoordinates: vi.fn(), })) describe('App', () => { beforeEach(() => { // 每次测试前清空间谍函数的调用记录 vi.clearAllMocks() render( <Provider store={store}> <App /> </Provider>, ) }) it('组件挂载时调用fetchCoordinates', () => { expect(locationSlice.fetchCoordinates).toHaveBeenCalledTimes(1) }) })
方案二:使用vi.spyOn单独Spy目标函数
通过spyOn为fetchCoordinates创建间谍包装,测试完成后恢复原函数:
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import { render } from '@testing-library/react' import { Provider } from 'react-redux' import App from '../App' import store from '../app/store' import * as locationSlice from '../features/location/locationSlice' describe('App', () => { let fetchCoordinatesSpy: vi.SpyInstance beforeEach(() => { // 为fetchCoordinates创建间谍函数,返回一个mock的action对象 fetchCoordinatesSpy = vi.spyOn(locationSlice, 'fetchCoordinates').mockReturnValue({ type: 'mock-action-type' } as any) render( <Provider store={store}> <App /> </Provider>, ) }) afterEach(() => { // 每次测试后恢复原函数,避免影响其他测试 fetchCoordinatesSpy.mockRestore() }) it('组件挂载时调用fetchCoordinates', () => { expect(fetchCoordinatesSpy).toHaveBeenCalledTimes(1) }) })
补充说明
两种方案的核心都是将fetchCoordinates转换为Vitest可跟踪的间谍函数,这样就能正常断言它的调用次数。如果你的测试还需要验证异步逻辑或dispatch的action,可以进一步扩展Mock的返回值,模拟成功/失败场景。
内容的提问来源于stack exchange,提问作者SeriousLee
相关产品推荐
相关产品推荐

