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

Jest Mock jose库SignJWT时遇‘不是构造函数’或‘sign不是函数’问题

解决Jest中Mock jose.SignJWT的问题

问题根源

  • 第一种Mock未添加__esModule: true,jose作为ES模块,Jest无法正确识别导出的类,导致SignJWT is not a constructor。
  • 第二种Mock中setProtectedHeader使用箭头函数,箭头函数的this不指向Mock实例,链式调用时返回值错误,后续调用sign时出现sign is not a function。

正确Mock方案

jest.mock('jose', () => ({
  __esModule: true,
  decodeJwt: jest.fn(() => Promise.resolve({})),
  SignJWT: jest.fn().mockImplementation(() => {
    const mockInstance = {
      setProtectedHeader: jest.fn(() => mockInstance),
      sign: jest.fn(() => Promise.resolve('mock-jwt-token')),
    };
    return mockInstance;
  }),
}));

方案说明

  1. __esModule: true:告诉Jest这是一个ES模块,确保导出的类能被正确识别为构造函数。
  2. 链式调用支持:通过定义mockInstance,让setProtectedHeader返回实例本身,完美模拟原类的链式调用逻辑(原类setProtectedHeader返回this)。
  3. 返回值匹配:sign方法返回Promise.resolve的字符串,与原方法的返回类型(Promise<string>)一致,避免测试中出现类型不兼容问题。

测试验证示例

在测试用例中,你可以这样验证Mock是否生效:

import { SignJWT } from 'jose';

test('should create and sign JWT', async () => {
  const token = await new SignJWT({ payload: 'test' })
    .setProtectedHeader({ alg: 'HS256' })
    .sign('secret-key');

  expect(SignJWT).toHaveBeenCalledWith({ payload: 'test' });
  expect(SignJWT.mock.instances[0].setProtectedHeader).toHaveBeenCalledWith({ alg: 'HS256' });
  expect(SignJWT.mock.instances[0].sign).toHaveBeenCalledWith('secret-key');
  expect(token).toBe('mock-jwt-token');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:39:57