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

Jest中Mock Axios无法处理默认请求头的问题求助

How to Fix "Cannot read property 'headers' of undefined" When Mocking Axios in Jest Tests

Got it, let's break down what's happening here and fix that error right away.

The root issue is simple: your current Jest mock only replaces axios.post, but it doesn't replicate the full structure of the axios object. When your action tries to access axios.defaults.headers.common, it hits undefined because your mock doesn't include the defaults property at all.

Solution 1: Update Your Axios Mock to Include defaults

Just extend your mock object to include the defaults structure that your code expects. This will let the action set the Authorization header without throwing an error. Here's how to adjust your mock:

import actions from "../../src/store/actions";
jest.mock("axios", () => ({
  post: (_url, _body, config) => {
    return new Promise((resolve) => {
      // Don't forget to add the `user` field here too—your action tries to access it!
      resolve({
        data: {
          success: { token: 'test' },
          user: { id: 1, username: 'test-user' }
        }
      });
    });
  },
  // Add the defaults structure to match axios's actual API
  defaults: {
    headers: {
      common: {}
    }
  }
}));

describe('login action', () => {
  it("lets the user login and triggers the login success mutator", async() => {
    const commit = jest.fn();
    const username = 'test';
    const password = 'test';
    await actions.login({commit}, {username, password});
    
    // Optional: Verify the commit was called correctly
    expect(commit).toHaveBeenCalledWith('LOGIN_SUCCESS', 'test', { id: 1, username: 'test-user' });
  });
});

Solution 2: Use jest.spyOn for More Control (Optional)

If you want to keep the rest of axios's default behavior and only mock the post method (plus verify that the header was actually set), using jest.spyOn is a cleaner approach:

import actions from "../../src/store/actions";
import axios from "axios";

describe('login action', () => {
  let postSpy;

  beforeEach(() => {
    // Mock axios.post to return your test data
    postSpy = jest.spyOn(axios, 'post').mockResolvedValue({
      data: {
        success: { token: 'test' },
        user: { id: 1, username: 'test-user' }
      }
    });
    // Reset headers between tests to avoid cross-test contamination
    axios.defaults.headers.common['Authorization'] = '';
    // Mock localStorage if you want to verify it's used
    Storage.prototype.setItem = jest.fn();
  });

  afterEach(() => {
    // Restore the original axios.post method after each test
    postSpy.mockRestore();
  });

  it("logs the user in, sets the auth header, and triggers the mutator", async() => {
    const commit = jest.fn();
    await actions.login({commit}, { username: 'test', password: 'test' });

    // Verify the auth header was set correctly
    expect(axios.defaults.headers.common['Authorization']).toBe('Bearer test');
    // Verify localStorage was updated
    expect(localStorage.setItem).toHaveBeenCalledWith('token', 'test');
    // Verify the commit action ran
    expect(commit).toHaveBeenCalledWith('LOGIN_SUCCESS', 'test', { id: 1, username: 'test-user' });
  });
});

Quick Notes to Avoid Other Issues

  • I added the user field to the mock response because your action tries to assign resp.data.user—without it, you'd hit another undefined error later.
  • If your tests run in an environment without localStorage (like Node.js), mocking Storage.prototype.setItem prevents errors and lets you verify that the token is being stored correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:47:55