Jest: child_process.exe c .mockImplentation не является функцией - PullRequest
0 голосов
/ 06 марта 2020

У меня есть функция, которая использует функцию 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 я попытался смоделировать вызов exe c следующим образом:

//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'). " - что я четко делаю.

1 Ответ

0 голосов
/ 07 марта 2020

Вы видите ошибку, потому что вы звоните mockImplentation вместо mockImplementation. К сожалению, когда вы исправите эту опечатку, тест все равно не пройдет.

Это потому, что вы вызываете метод promisify для exec, что позволяет использовать его в качестве обещания. promisify делает под капотом преобразование из функции на основе асинхронного обратного вызова (где обратный вызов помещается в последний параметр и вызывается с ошибкой в ​​качестве первого параметра, а данные в качестве второго) в функцию на основе обещания.

Итак, чтобы метод 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');
    });
});
...