require.main.require works but not inside Mocha test

天涯浪子 提交于 2019-12-05 03:42:10

require.main points to the module that was run directly from node. So, if you run node app.js, then require.main will point to app.js. If, on the other hand, you ran it using mocha, then require.main will point to mocha. This is likely why your tests are failing.

See the node docs of more details.

Because require.main was not index.html in my node-webkit app when running mocha tests, it threw errors left and right about not being able to resolve modules. Hacky fix in my test-helper.js (required first thing in all tests) fixed it:

var path = require('path')
require.main.require = function (name) {
    // navigate to main directory
    var newPath = path.join(__dirname, '../', name)
    return require(newPath)
}

This feels wrong, though it worked. Is there a better way to fix this? It's like combining some of the above solutions with #7 to get mocha testing working, but modifying main's require just to make everything work when testing feels really wrong.

For other avoid-the-".."-mess solutions, see here: https://gist.github.com/branneman/8048520

This is pretty old, but here is my solution.

I needed a test harness module to be published to a private registry and required by the mocha test suite. I wanted the calling test code to pass the code under test to the harness rather than requiring it directly:

var harness = require('test-harness');
var codeUnderTest = harness('../myCode');  

Inside harness (which was found in the project node_modules directory), I used the following code to make require find the correct file:

        if (!path.isAbsolute(target)) {
            target = path.join(path.dirname(module.parent.paths[0]), target);
        }
        var codeUndertest = require(target);
        ...
        return codeUnderTest;

This relies on the require path resolution that always starts with looking for a node_modules subdirectory relative to the calling file. Couple that with module.parent and you can get access to that search path. Then just remove the trailing node_modules part and concatenate the relative filename.

For other scenarios not using relative paths, this could be accomplished with the options parameter to require:

        var codeUndertest = require(target, {paths: module.parent.paths});
        ...
        return codeUnderTest;

And the two could be combined as well. I used the first form because I was actually using proxyquire which does not offer the paths option.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!