4

Working on getting a project transitioned over from Mocha to Jest to take advantage of the speed in running tests as well as the Jest framework itself and running into an issue. Rewire is used pretty extensively in the codebase and I'm having an issue when running the gulp-jest task and only for those files that use rewire. I assume it has something to do with modules loading or not loading, but I'm stumped. Here's the really bare-bones gulp task, doesn't have much to it. I've already run through an extensive codemod on the codebase and many tests pass, just not those that use rewire.

gulp.task('jest', function() {
    process.env.NODE_ENV = 'test';
    return gulp.src('name/path').pipe(
        jest({
            preprocessorIgnorePatterns: ['<rootDir>/node_modules/'],
            automock: false,
            resetModules: true,
            setupFiles: ['./jestsetup.js']
        })
    );
});

gulp.task('newtest', function(callback) {
    runSequence('env', 'jest', callback);
});

Any time the rewire-related files are run, they complain about the file not being found. Am I missing anything here? I'm certain the modules themselves have the correct path set for the require.

Here's the actual error from jest/rewire:

 FAIL  path/to/folder/file/app.test.js
  ● Test suite failed to run

    Cannot find module '../../../../path/to/folder/file/app'

      at Function.Module._resolveFilename (module.js:469:15)
      at internalRewire (node_modules/rewire/lib/rewire.js:23:25)
      at rewire (node_modules/rewire/lib/index.js:11:12)
      at Object.<anonymous (path/to/folder/file/app.test.js:10:14)
      at process._tickCallback (internal/process/next_tick.js:109:7)

Using node 6.X, jest 20.x

Thanks in advance!

skyboyer
  • 22,209
  • 7
  • 57
  • 64
markthethomas
  • 4,391
  • 2
  • 25
  • 38

2 Answers2

1

Jest has its own mechanism of mocking import, it's called jest.mock.

You will need to switch to using that instead of rewire.

Example

// banana.js
module.exports = () => 'banana';

// __tests__/test.js
jest.mock('../banana');

const banana = require('../banana'); // banana will be explicitly mocked.

banana(); // will return 'undefined' because the function is auto-mocked.

example was taken from here

Car4p17
  • 45
  • 1
  • 6
felixmosh
  • 32,615
  • 9
  • 69
  • 88
  • 3
    Right, I understand that, but is there any way around it? We use rewire really heavily and it's non-trivial to have to re-write using jest's mocking tools. Wonder if I could dynamically dontMock things and bypass Jest? – markthethomas Aug 26 '17 at 06:48
  • *I believe it's `unmock` now – markthethomas Aug 26 '17 at 06:48
  • Maybe you can monkey patch `rewire`, write your own "rewire" function that in the internals it will use jest.mock. Put it on the jest.setup file https://jest-bot.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string – felixmosh Aug 26 '17 at 06:51
  • Interesting, seems like something like that could work. Was hoping I wouldn't have to resort to something like this but it'd be less work than rewriting a 1,000 tests :) – markthethomas Aug 26 '17 at 06:52
  • 1
    Second option is to use codemod, something like that https://github.com/skovhus/jest-codemods, or write one :] take an inspiration from https://github.com/skovhus/jest-codemods/blob/master/src/utils/proxyquire.js – felixmosh Aug 26 '17 at 06:55
  • 1
    Could work! The only thing I could see being a problem is that our usage of rewire isn't just syntactic, it also has an aspect that might be tough with a codemod. Tests are littered w/ module reversions that would all need manual cleanup :/ – markthethomas Aug 26 '17 at 07:07
-1

To my surpise, Proxyquire was not compatible with jest. To mock a dependency you would need to utilize a mocking library, like rewiremock.

Please have a look at this answer and this REPL example on how to successfully mock dependent packages.

Menelaos Kotsollaris
  • 5,776
  • 9
  • 54
  • 68