You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest报错:function must be a mock or spy,测试App动作时断言未触发

Hey there! Let's break down what's going on with your test case issue and fix it step by step.

First: Why the last expect isn't running

The most common culprit here is unhandled asynchronous code in your action. If your action uses promises, async/await, or callbacks, your test might finish executing before the action completes—so the final expect never gets triggered.

Fix for async actions:

Make sure your test waits for the action to finish. Here are a few ways to do this:

  • Use async/await if your action returns a promise:
    test('should trigger final assertion', async () => {
      const dispatch = jest.fn();
      // Wait for the async action to resolve
      await yourAsyncAction()(dispatch);
      // Now this expect will run after the action completes
      expect(dispatch).toHaveBeenCalledWith({ type: 'FINAL_ACTION' });
    });
    
  • Use a done callback for callback-based async logic:
    test('should trigger final assertion', (done) => {
      const dispatch = jest.fn();
      yourCallbackAction((result) => {
        expect(dispatch).toHaveBeenCalledWith({ type: 'FINAL_ACTION', result });
        done(); // Signal Jest the test is complete
      });
    });
    

Second: The "jest function must be a mock or spy" error

This happens when you try to use Jest's mock-specific matchers (like toHaveBeenCalled(), toHaveBeenCalledWith()) on a regular function instead of a Jest mock/spy.

Fix for mock/spy requirements:

You need to replace the function you're asserting on with a Jest mock. Here's how:

  1. Create a mock function with jest.fn():
    // Instead of a regular function:
    // const myFunction = () => {};
    
    // Use a mock:
    const myFunction = jest.fn();
    
  2. If the function comes from an external module, mock the entire module with jest.mock():
    // Mock the api module that your action uses
    jest.mock('../api');
    import { fetchData } from '../api';
    
    test('should call fetchData', async () => {
      const dispatch = jest.fn();
      // Set up mock return value
      fetchData.mockResolvedValue({ data: 'test' });
      await yourAction()(dispatch);
      // Now this assertion is valid because fetchData is a mock
      expect(fetchData).toHaveBeenCalled();
    });
    

Quick sanity checks

  • Double-check that your mock function is actually being used by your action (not a different instance of the function).
  • Look for uncaught errors in your action—if an error is thrown before reaching the final logic, the test will terminate early without running the last expect. You can wrap the action call in a try/catch to debug this:
    test('debug action errors', async () => {
      try {
        await yourAction()(dispatch);
        expect(...);
      } catch (err) {
        console.error('Action threw an error:', err);
        throw err; // Re-throw to let Jest report the error
      }
    });
    

内容的提问来源于stack exchange,提问作者FranWalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:42:57