独立于web浏览器的JavaScript单元测试
我有客户端JavaScript,它不会以任何方式与DOM或web浏览器交互。我想在Travis CI中对这段代码的功能进行单元测试(这只是一个奇特的数据库/缓冲区),而无需启动web浏览器。命令行JavaScript让我觉得我需要node.js。我浏览了各种单元测试库,并决定使用Mocha,因为它简单,但是使用基于node.js的库测试基于浏览器的模块/类似乎过于困难 具体来说,我想测试这个(简化的)浏览器JavaScript有效代码:独立于web浏览器的JavaScript单元测试,javascript,node.js,unit-testing,travis-ci,Javascript,Node.js,Unit Testing,Travis Ci,我有客户端JavaScript,它不会以任何方式与DOM或web浏览器交互。我想在Travis CI中对这段代码的功能进行单元测试(这只是一个奇特的数据库/缓冲区),而无需启动web浏览器。命令行JavaScript让我觉得我需要node.js。我浏览了各种单元测试库,并决定使用Mocha,因为它简单,但是使用基于node.js的库测试基于浏览器的模块/类似乎过于困难 具体来说,我想测试这个(简化的)浏览器JavaScript有效代码: // I need this NameSpace to o
// I need this NameSpace to organise my code and isolate from other code
var Nengo = {};
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
for(var i = 0; i < this.data.length; i++){
this.data[i].push(row[i+1]);
}
}
它失败,出现以下错误:
/home/saubin/javascript_test/test/simple_test.js:5
var data_store = new Nengo.DataStore(2);
^
ReferenceError: Nengo is not defined
at Suite.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:5:22)
at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
at Object.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:4:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
at Array.forEach (native)
at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:189:14)
at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:422:31)
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:935:3
/home/saubin/javascript\u test/test/simple\u test.js:5
var数据存储=新的Nengo.数据存储(2);
^
ReferenceError:未定义Nengo
在套房。(/home/saubin/javascript_test/test/simple_test.js:5:22)
位于context.descripe.context.context(/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
反对。(/home/saubin/javascript_test/test/simple_test.js:4:1)
在模块处编译(Module.js:456:26)
在Object.Module.\u extensions..js(Module.js:474:10)
在Module.load(Module.js:356:32)
在Function.Module.\u加载(Module.js:312:12)
at Module.require(Module.js:364:17)
根据需要(模块js:380:17)
at/usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
at Array.forEach(本机)
在Mocha.loadFiles(/usr/local/lib/node_modules/Mocha/lib/Mocha.js:189:14)
在Mocha.run(/usr/local/lib/node_modules/Mocha/lib/Mocha.js:422:31)
反对。(/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
在模块处编译(Module.js:456:26)
在Object.Module.\u extensions..js(Module.js:474:10)
在Module.load(Module.js:356:32)
在Function.Module.\u加载(Module.js:312:12)
位于Function.Module.runMain(Module.js:497:10)
启动时(node.js:119:16)
在node.js:935:3
解决这个问题的一种方法是放弃节点,将测试结果输出到无头浏览器的DOM中,并获得结果,但这似乎是一个很大的开销。我可以更改代码的结构以与Node.js兼容吗?由于缺乏这方面的知识,还有其他解决方案我没有看到吗?您可以让代码“node.js感知”,这样它就可以将全局定义放入实际的全局上下文中,同时仍然与浏览器环境完全兼容:
if (typeof window !== "undefined") {
// in browser, define global to be an alias for window
// so global can be used to refer to the global namespace in
// both the browser and node.js
var global = window;
}
global.Nengo = {};
(function() {
var Nengo = global.Nengo;
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
this.data.push(row.slice(1));
}
})();
if(窗口类型!=“未定义”){
//在浏览器中,将“全局”定义为窗口的别名
//因此,可以使用global来引用中的全局命名空间
//浏览器和node.js
var全局=窗口;
}
global.Nengo={};
(功能(){
var Nengo=global.Nengo;
Nengo.DataStore=函数(dims){
this.times=[];
这个.data=[];
对于(变量i=0;i
然后,请记住,任何全局定义都必须显式地分配给
global
名称空间。在node.js中,这将把它们分配到node.js中的实际global
命名空间。在浏览器中,这将把它们分配给窗口
对象,该对象是浏览器中的全局名称空间。尽管@jfrieen00的答案在技术上是正确的,但我后来提出了另一个答案
首先,我需要重构JavaScript代码,在数据存储
文件之外声明我的命名空间。然后我将Nengo全局变量声明为jfriend00 descriptionsglobal.Nengo={}代码>,但仅在我的Mocha测试文件中
这样,当我在web浏览器和单元测试中运行时,我的代码将按预期进行测试。Nengo是否作为节点模块存在?如何加载它?它不是一个节点模块,因为它只在客户端浏览器中运行,根据我的理解,它是一个实际的节点模块,我必须在服务器端运行它。我正在按上面的代码所示加载它,主要是因为我不知道如何加载它。@DaveNewton在我上一篇评论中忘了提到你,所以库只在客户端运行,节点只在服务器端运行。。。这样发送不会很好,不是吗?@DaveNewton是的,我意识到Node.js!=JavaScript。然而,它们的单元测试框架似乎是相同的,所以这让我感到困惑。我可以在命令行中测试客户端JavaScript代码吗?或者我必须使用浏览器吗?您在我的代码中添加闭包有什么特殊原因吗?@Seanny123-只是为了保存一些键入,以便我可以定义一个名为Nengo
的局部变量,该变量可以像以前一样使用。如果要为每个方法定义键入global.Nengo.Datastore=function(){…}
,则不需要闭包。
if (typeof window !== "undefined") {
// in browser, define global to be an alias for window
// so global can be used to refer to the global namespace in
// both the browser and node.js
var global = window;
}
global.Nengo = {};
(function() {
var Nengo = global.Nengo;
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
this.data.push(row.slice(1));
}
})();