我试图弄清楚如何在nodejs中测试内部(即不导出)函数(最好使用mocha或jasmine)。我也不知道!
假设我有一个这样的模块
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
以及以下测试(摩卡):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
是否有任何方法可以对notExported函数进行单元测试,而不实际导出它,因为它不打算公开?
我发现了一种非常简单的方法,可以让你在测试中测试、监视和模拟这些内部函数:
假设我们有一个这样的节点模块:
mymodule.js:
------------
"use strict";
function myInternalFn() {
}
function myExportableFn() {
myInternalFn();
}
exports.myExportableFn = myExportableFn;
如果我们现在想测试并监视和模拟myInternalFn,而不是在生产中导出它,我们必须像这样改进文件:
my_modified_module.js:
----------------------
"use strict";
var testable; // <-- this is new
function myInternalFn() {
}
function myExportableFn() {
testable.myInternalFn(); // <-- this has changed
}
exports.myExportableFn = myExportableFn;
// the following part is new
if( typeof jasmine !== "undefined" ) {
testable = exports;
} else {
testable = {};
}
testable.myInternalFn = myInternalFn;
现在你可以测试,间谍和模拟myInternalFn在任何地方,你使用它作为测试。myInternalFn和在生产中它是不导出的。
这是不推荐的实践,但如果您不能像@Antoine建议的那样使用rewire,则始终可以读取文件并使用eval()。
var fs = require('fs');
const JsFileString = fs.readFileSync(fileAbsolutePath, 'utf-8');
eval(JsFileString);
在为遗留系统进行客户端JS文件单元测试时,我发现这很有用。
JS文件会在window下设置很多全局变量,没有任何require(…)和模块。exports语句(没有像Webpack或Browserify这样的模块绑定器可以删除这些语句)。
这使得我们可以在客户端JS中集成单元测试,而不是重构整个代码库。
我一直在使用一种不同的方法,没有任何依赖:
有一个包含我想测试的所有本地函数的__testing导出,该值取决于NODE_ENV,因此它只在测试中可访问:
// file.ts
const localFunction = () => console.log('do something');
const localFunciton2 = () => console.log('do something else');
export const exportedFunction = () => {
localFunction();
localFunciton2();
}
export const __testing = (process.env.NODE_ENV === 'test') ? {
localFunction, localFunction2
} : void 0;
// file.test.ts
import { __testing, exportedFunction } from './file,ts'
const { localFunction, localFunction2 } = __testing!;
// Now you can test local functions