首页 > 解决方案 > 开玩笑:child_process.exec.mockImplentation 不是函数

问题描述

我有一个使用该功能的child_process.exec功能:

//serverUtils.js:
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);

  async getUpstreamRepo() {
    try {
      const forkConfig = (await exec('git remote get-url upstream')).stdout;
      let upstreamRepo = forkConfig.replace('git@github.com:', '');
      upstreamRepo = upstreamRepo.replace(/\r?\n|\r/g, '');
      return upstreamRepo;
    } catch (error) {
      console.error(error);
      throw error;
    }
  },

在查看了这个 SO post 之后,我尝试像这样模拟 exec 调用:

//serverUtils.test.js:
const child_process = require('child_process');
jest.mock('child_process')
describe('Test Class', () => {
    ....
    it('check upstream repo', async () => {      

    child_process.exec.mockImplentation(jest.fn().
        mockReturnValueOnce('git@github.com:mock/url.git'))

    await expect(serverScript.getUpstreamRepo()).
        resolves.toEqual('mock/url.git');
    });
 }

但是,我得到child_process.exec.mockImplentation is not a function 了正如链接的帖子所解释的那样,“ Jest 文档说,在模拟 Node 的核心模块时,需要调用 jest.mock('child_process') 。” ——我显然是这样做的。

标签: node.jsunit-testingjestjschild-process

解决方案


您看到的错误是因为您正在调用mockImplentation而不是mockImplementation. 不幸的是,当您更正该错字时,测试仍然无法通过。

promisify这是因为您正在调用exec方法,允许将其用作承诺。幕后promisify工作是从基于异步回调的函数(其中回调放置在最后一个参数并以错误作为第一个参数和数据作为第二个参数调用)转换为基于承诺的函数。

因此,为了使该promisify方法能够正常工作,您必须模拟该exec方法,以便它调用回调参数以便解决 Promise。

另外,请注意,您正在stdout从调用结果中读取参数exec,因此在返回的数据中,您必须发送具有该属性的对象。

考虑到所有这些:

it('check upstream repo', async () => {
    child_process.exec.mockImplementation((command, callback) => {
        callback(null, { stdout: 'git@github.com:mock/url.git' });
    });

    await expect(serverScript.getUpstreamRepo()).
        resolves.toEqual('mock/url.git');
});

另一种可能的解决方案是直接模拟该promisify方法:

jest.mock('util', () => ({
    promisify: jest.fn(() => {
        return jest.fn().mockResolvedValue({ stdout: 'git@github.com:mock/url.git' });
    })
}));

describe('Test Class', () => {
    it('check upstream repo', async () => {
        await expect(serverScript.getUpstreamRepo()).
            resolves.toEqual('mock/url.git');
    });
});

推荐阅读