Ben S
Ben S

Reputation: 568

Mocking shelljs with Jest - [TypeError: shell.exec is not a function]

As mentioned in my previous question about mocking, I am new to Jest and testing and I seem to be getting some curveballs.

This time around I am having trouble mocking shelljs in my CLI application.

Automocking jest.mock('shelljs'); didn't work and errored as:[TypeError: shell.exec is not a function]

So I went ahead and tried to use mockImplementation()

jest.mock('shelljs', () => {
  return jest.fn().mockImplementation(() => {
    return {
      exec: () => {}
    };
  });
});

To my surprise I am still getting the same error message

Any pointers would be much apprecieted.

UPDATE 08/04/2020:

As per Teneff's reply below, the mocking works fine with:

jest.mock('shelljs', () => {
  return {
    exec: jest.fn()
  };
});

Now I'm getting timeouts as my call of shell.exec() is async and have a callback that resolves my promise.

My goal is to mock shell.exec() to just resolve the promise, but it goes into waiting around and Jest times out.

Upvotes: 1

Views: 1359

Answers (3)

BTL
BTL

Reputation: 4656

Teneff answer worked for me. But as I wanted to mock different shell responses I improved it like that :

const shelljs = require('shelljs');

jest.mock('shelljs');

describe('Run the test suite', () => {
  test('it should ...', async () => {
    shelljs.exec = jest.fn().mockImplementation(() => ({ code: 0 }));
    ...
    expect(...);
  });
  test('it should ...', async () => {
    shelljs.exec = jest.fn().mockImplementation(() => ({ code: 1 }));
    ...
    expect(...);
  });
});

Upvotes: 2

Ben S
Ben S

Reputation: 568

Taking onboard Teneff's answer I realised that the timeout happens, because I mocked shell.exec successfully however I have used it's async version exec(command [, options] [, callback]) so I tried first logging out the arguments and it worked.

All was left to do to call the callback and voila, my test works.

jest.mock('shelljs', () => {
  return {
    exec: jest.fn((_, __, callback) => callback())
  };
});

Upvotes: 4

Teneff
Teneff

Reputation: 32158

As you're using shell as an object with .exec property your jest.mock factory function should return an object with exec property

jest.mock('shelljs', () => {
  return { exec: jest.fn() }
});

Upvotes: 2

Related Questions