Jest and Bower Module loading in jest tests

1.7k views Asked by At

Lets say I have a project that uses bower, grunt, bowerify(with shim) and since I love Jest so much I want to test with that. How in the world do I get jest to see my browserify shim modules when it runs tests. I use grunt, to kick off the npm test command. Here is my package.json file.

"browser": {
    "jquery": "./bower_components/jquery/dist/jquery.js",
    "foundation": "./bower_components/foundation/js/foundation/foundation.js",
    "fastclick": "./bower_components/fastclick/lib/fastclick.js",
    "greensock-tm": "./bower_components/gsap/src/uncompressed/TweenMax.js",
    "greensock-css": "./bower_components/gsap/src/uncompressed/plugins/CSSPlugin.js",
    "greensock-time": "./bower_components/gsap/src/uncompressed/TimelineMax.js",
    "scrollmagic": "./bower_components/ScrollMagic/js/jquery.scrollmagic.js",
    "handlebars": "./bower_components/handlebars/handlebars.runtime.js"
  },
  "browserify-shim": {
    "jquery": "$",
    "greensock-css": "CSSPlugin",
    "fastclick": "FastClick",
    "greensock-tm": "TweenMax",
    "greensock-time": "TimelineMax",
    "scrollmagic": "ScrollMagic",
    "foundation": "foundation",
    "handlebars": "Handlebars"
  },
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  },

Right now I almost have this worked out by doing this in my grunt file before I run the test.

grunt.registerTask("shimBowerForTests",function(){
    var readJson = require('read-package-json');
    var fs = require('fs');
    var remapify = require('remapify');
    readJson('./package.json', console.error, false, function (er, data) {
      if (er) {
        throw "There was an error reading the file";
      }
      var packages = data.browser;
      var browserify = require('browserify');
      for (var key in packages){
        var b = browserify();
        var wstream = fs.createWriteStream("devjs/test/modules/"+key+'.js');
        b.add(packages[key]);
        b.bundle().pipe(wstream);
      }
    });
  });

and.

exec: {
      jestTest: {
        command: 'cp -r devjs/modules devjs/test/modules && npm test'
      }
    }

The problem is that using browserify so combine everything for the browser works great with my setup and I can require my shimmed modules like this. require('jquery') //example but in the jest cli the test fail because they can find the module unless I somehow prefix it with ./, like so require('./jquery')

2

There are 2 answers

2
austbot On BEST ANSWER

UPDATE

Instead of using my below solution you should opt for using Karma,karma browserify. I have converted the below solution into using karma and it is working much much better.

----------------------OLD ANSWER What I actually did to solve this was, used the Jest source preprocessor to rewrite the require statement to look for a module in a certain directory in my /tests/ folder that I have created using grunt. The Folder contains the files listed in my browserify-shim, browser section of the package.json file.

EDIT: Here is how I shim bower, I made this script in the Gruntfile.js that puts all the bower modules and any commonjs modules that I need into an accessible directory.

grunt.registerTask("shimBowerForTests", function() {
    var readJson = require('read-package-json');
    var fs = require('fs');
    readJson('./package.json', console.error, false, function(er, data) {
      if (er) {
        throw "There was an error reading the file";
      }
      var packages = data.browser;
      var shim = data['browserify-shim'];
      var browserify = require('browserify');
      var exclude = ["jquery.maskedinput", "jquery"];
      for (var key in packages) {
        var b = browserify();
        var wstream = fs.createWriteStream("devjs/test/modules/" + key + '.js');
        if (shim[key] !== undefined && exclude.indexOf(key) === -1) {
          b.add(packages[key]);
          b.bundle().pipe(wstream);
        } else {
          var rstream = fs.createReadStream(packages[key]);
          rstream.pipe(wstream);
        }
      }
    });
  });

Then in the Jest pre processor file I do this.

module.exports = {
  process: function(src, path) {
    var src2= src.replace(/require\([\"\']([^\.\'\"]+)[\"\']\)/g, "require(\'../modules/$1\')");
    src2= src2.replace(/jest\.dontMock\([\"\']([^\.\'\"]+)[\"\']\)/g, "jest.dontMock(\'../modules/$1\')");
    return src2;
  }
};
0
Nathan Harper On

I'm guessing that the problem is that you've only installed your shimmed modules with bower. If you want them to work in node/jest, you'll have to install them with npm as well. Then just make sure Jest isn't mocking anything in the node_modules directory, and it should find all the required modules in there as long as the names match up.

Your Jest config in package.json should look like:

"jest": {
  "unmockedModulePathPatterns": [
    "./node_modules"
  ]
}

And then just download all the dependencies.

npm install jquery --save-dev