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

如何在Jest中Mock子进程中Grunt任务调用的request模块?

问题分析

你猜的没错,Jest 的 Mock 仅作用于当前进程,通过 exec 启动的子进程是完全独立的 Node.js 实例,不会继承主进程的 Mock 模块,所以子进程里调用的 request 还是原模块。

解决方案

这里提供几个可行的解决思路:

1. 直接测试任务核心逻辑(推荐)

把 Grunt 任务里依赖 request 的核心逻辑抽成单独模块,测试时直接导入该模块验证,无需启动子进程执行 Grunt 命令,这样 Jest 的 Mock 就能正常生效。

示例代码:
task-logic.js

const request = require('request');

module.exports = function fetchData(url, callback) {
  request(url, function(error, response, body) {
    // 原任务中的业务逻辑
    callback(error, response, body);
  });
};

task.js

const fetchData = require('./task-logic');

// Grunt 任务注册逻辑
grunt.registerTask('task', function() {
  const done = this.async();
  fetchData('目标URL', function(error, response, body) {
    // 任务后续处理逻辑
    done();
  });
});

task.spec.js

const fetchData = require('./task-logic');
const request = require('request');
jest.mock('request');

describe('UT for something', () => {
  it('should pass', async () => {
    request.mockImplementation((url, cb) => {
      cb(undefined, undefined, 'mocked response');
    });

    await new Promise((resolve) => {
      fetchData('测试URL', resolve);
    });

    // 断言逻辑,比如验证request被正确调用
    expect(request).toHaveBeenCalledWith('测试URL', expect.any(Function));
  });
});

2. 给子进程注入Mock模块

如果必须通过子进程执行Grunt任务,可以通过环境变量引导子进程优先加载Mock版本的request:

  • 先编写Mock版request模块,比如__mocks__/request.js:
module.exports = function(url, cb) {
  cb(undefined, undefined, 'mocked response');
};
  • 执行子进程时,设置NODE_PATH环境变量让子进程优先加载Mock模块:
const exec = require('child_process').exec;

describe('UT for something', () => {
  it('should pass', async () => {
    const execChild = () => {
      return new Promise((resolve, reject) => {
        exec('grunt task', {
          env: { 
            ...process.env, 
            NODE_PATH: './__mocks__:' + (process.env.NODE_PATH || '') 
          }
        }, (error, stdout, stderr) => {
          if (error) reject(error);
          resolve(stdout || stderr);
        });
      });
    };

    await execChild();
    // 后续断言逻辑
  });
});

注意:Mock模块的导出结构必须和原request模块一致,否则会引发逻辑错误。

3. 通过环境变量切换逻辑分支

在task.js中根据环境变量判断是否加载Mock模块:

let request;
if (process.env.NODE_ENV === 'test') {
  request = require('./__mocks__/request');
} else {
  request = require('request');
}

// 后续Grunt任务注册及业务逻辑

执行子进程时设置测试环境变量:

exec('grunt task', { env: { ...process.env, NODE_ENV: 'test' } }, ...);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:53:09