Unit Testing Commander Scripts With Jest

Ole Ersoy
2 min readJan 22, 2019
Photo by Louis Reed on Unsplash

Scenario

We are creating a Commander based CLI and we wish to unit test the result of running it with Jest.

Approach

First we will scaffold an example project.

mkdir cli
cd cli
npm init -y
npm i -S commander
npm i -D jest
touch index.js //The commander script
touch index.spec.js //The JEST Unit test

Commander Script

In index.js implement the script:

#!/usr/bin/env nodevar program = require('commander');program
.version('1.0.0')
.option('-p, --parameters [type]', 'Add parameter')
.parse(process.argv);
if (program.parameter) console.log(' - %s parameter', program.parameter);

Jest Unit Test

The cli function runs the command line defined in index.js returns a Promise that contains the result of running the Commander command line script:

let path = require('path');
let exec = require('child_process').exec;
test('Code should be 0', async () => {
let result = await cli(['-p', 'parameter'], '.');
expect(result.code).toBe(0);
})
function cli(args, cwd) {
return new Promise(resolve => {
exec(`node ${path.resolve('./index')} ${args.join(' ')}`,
{ cwd },
(error, stdout, stderr) => { resolve({
code: error && error.code ? error.code : 0,
error,
stdout,
stderr })
})
})}

Make sure that scripts is configured properly in package.json :

"scripts": {
"test": "jest"
}

Run npm test . This will run the unit test in index.spec.js .

Change Runtime Directory

We pass . as the current runtime directory in the statement:

let result = await  cli(['-p', 'parameter'], '.');

The . is the cwd or current working directory parameter. If you change this to something else like ./sandbox/ then the script will consider ./sandbox to be the current runtime directory.

Real World Example

Check out index.spec.js for the SuperflyCSS CLI:

--

--