一尘不染

如何对需要其他模块的Node.js模块进行单元测试,以及如何模拟全局require函数?

node.js

这是一个简单的示例,它说明了我的问题的症结所在:

var innerLib = require('./path/to/innerLib');

function underTest() {
    return innerLib.doComplexStuff();
}

module.exports = underTest;

我正在尝试为此代码编写单元测试。如何在innerLibrequire完全嘲笑功能的情况下嘲笑对的要求?

因此,这是我试图模拟全局变量,require并发现即使这样做也不起作用:

var path = require('path'),
    vm = require('vm'),
    fs = require('fs'),
    indexPath = path.join(__dirname, './underTest');

var globalRequire = require;

require = function(name) {
    console.log('require: ' + name);
    switch(name) {
        case 'connect':
        case indexPath:
            return globalRequire(name);
            break;
    }
};

问题在于文件require内部的功能underTest.js实际上尚未被模拟。它仍然指向全局require功能。因此,看来我只能require在进行模拟的同一个文件中模拟出该函数。如果我使用全局require来包含任何内容,即使在覆盖本地副本之后,所需的文件仍将具有全球require参考。


阅读 231

收藏
2020-07-07

共1个答案

一尘不染

您现在可以!

我发布了proxyquire,它将在测试模块时覆盖模块内部的全局需求。

这意味着您无需 更改代码 即可为所需模块注入模拟。

Proxyquire有一个非常简单的api,它可以解析您要测试的模块,并通过一个简单的步骤传递其所需模块的模拟/存根。

@Raynos是正确的,传统上,您必须诉诸不太理想的解决方案才能实现该目标或进行自下而上的开发

这就是我创建proxyquire的主要原因-允许自上而下的测试驱动开发而无任何麻烦。

请查看文档和示例,以判断它是否适合您的需求。

2020-07-07