开玩笑:child_process.exec.mockImplentation不是一个函数

时间:2020-03-06 00:19:43

标签: node.js unit-testing jestjs child-process

我有一个使用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;
    }
  },

After looking at this 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 documentation说,在模拟Node的核心模块时,需要调用jest.mock('child_process')。” -我很清楚。

1 个答案:

答案 0 :(得分:0)

您看到的错误是因为您正在呼叫mockImplentation而不是mockImplementation。不幸的是,当您纠正错字时,测试仍然无法通过。

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

因此,为了使promisify方法起作用,您将必须模拟exec方法,以便它调用回调参数以使承诺得以解决。

另外,请注意,您正在从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');
    });
});