我有一个使用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')。” -我很清楚。
答案 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');
});
});