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

Jest.spyOn测试express-validator报"Cannot use spyOn..."错误的解决方法

Express-validator validationResult Jest Mock 报错修复

错误含义

“Cannot use spyOn on a primitive value; undefined given” 表示调用jest.spyOn时,第二个参数指定的属性在第一个参数对象中不存在(值为undefined),且spyOn仅能用于监听对象的方法,无法作用于原始值。

问题根源

控制器中通过命名导入引入validationResult:

import { validationResult } from "express-validator";

但测试代码里导入了express-validator的默认导出对象validator,并试图监听它的validationResult属性——而express-validator的默认导出对象并不包含该属性,导致spyOn获取到的目标属性为undefined,触发报错。

修复方案

以下两种方式均可解决问题:

方式1:导入所有导出内容,正确监听命名导出的函数

修改测试代码的导入逻辑,用import * as validator from "express-validator"将所有导出内容加载到validator对象上,确保validator.validationResult存在:

import RegistrationController from "./registration.controller";
// 修改导入方式:将所有导出内容导入到validator对象
import * as validator from "express-validator";

describe("registration", () => {
  const { registration } = RegistrationController;

  let req = {},
    res = {
      status: jest.fn().mockReturnThis(),
      json: jest.fn()
    },
    next = jest.fn();

  it('验证失败时应调用next("Houston, we have a problem")', async () => {
    const validationResultMock = {
      isEmpty: () => false,
    };

    jest
      .spyOn(validator, "validationResult")
      .mockImplementation(() => validationResultMock);

    await registration(req, res, next);

    expect(next).toBeCalledWith("Houston, we have a problem");
  });
});

方式2:直接mock整个express-validator模块

通过jest.mock直接模拟模块导出,逻辑更简洁:

import RegistrationController from "./registration.controller";
import { validationResult } from "express-validator";

// mock整个express-validator模块,保留其他导出的真实实现
jest.mock("express-validator", () => ({
  ...jest.requireActual("express-validator"),
  validationResult: jest.fn(),
}));

describe("registration", () => {
  const { registration } = RegistrationController;

  let req = {},
    res = {
      status: jest.fn().mockReturnThis(),
      json: jest.fn()
    },
    next = jest.fn();

  it('验证失败时应调用next("Houston, we have a problem")', async () => {
    // 指定validationResult的返回值
    (validationResult as jest.Mock).mockReturnValue({
      isEmpty: () => false,
    });

    await registration(req, res, next);

    expect(next).toBeCalledWith("Houston, we have a problem");
  });
});

注:上述代码中给res对象mock了status和json方法,可避免测试过程中出现“res.status is not a function”的控制台警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:43:20