Brandon Olivier
Brandon Olivier

Reputation: 578

Mock shell command output in Jest

I'm writing a cli tool and I'm trying to write tests for it in Jest. I have some functions that call out to git, but I need to mock the returns from those calls or they aren't going to be consistent.

The code I'm using to call out to the shell looks like this.

import { exec } from "child_process";

function execute(command) {
  return new Promise((resolve, reject) => {
    exec(command, resolve);
  });
}

export const getGitDiff = function () {
  return execute("git diff")
};

How can I write a test for that in Jest?

What I tried was

import { getGitDiff } from './getGitDiff';

describe('get git diff', () => {
  it('should send "git diff" to stdin', () => {
    const spy = jest.spyOn(process.stdin, 'write');
    return getGitDiff().then(() => {
      expect(spy).toHaveBeenCalled();
    })
  });
});

Upvotes: 3

Views: 1634

Answers (1)

Brandon Olivier
Brandon Olivier

Reputation: 578

I ended up creating a new file called child_process.js and using the genMockFromModule functionality in Jest to stub the whole module and reimplemented some of the functions like this

const child_process = jest.genMockFromModule('child_process');

const mockOutput = {}

const exec = jest.fn().mockImplementation((command, resolve) => {
    resolve(mockOutput[command]);
})

const __setResponse = (command, string) => {
    mockOutput[command] = string;
}

child_process.exec = exec
child_process.__setResponse = __setResponse;

module.exports = child_process;

and I have a test like

const child_process = jest.genMockFromModule('child_process');

const mockOutput = {}

const exec = jest.fn().mockImplementation((command, resolve) => {
    resolve(mockOutput[command]);
})

const __setResponse = (command, string) => {
    mockOutput[command] = string;
}

child_process.exec = exec
child_process.__setResponse = __setResponse;

module.exports = child_process;

Upvotes: 4

Related Questions