编写可测试的JavaScript代码
作者:网络转载 发布时间:[ 2016/6/2 15:03:04 ] 推荐标签:Javascript web测试
在运行测试套件时,length 断言会测试失败,但是这里很难弄清它为什么会失败。问题在于上一次测试中 dataStore 的状态留了下来。如果只是给测试重新排序的话 length 测试会通过,但是会有红色标志标明某处出现了问题。我们当然可以使用 setup 或者 teardown 方法,用恢复 dataStore 的状态来修复此问题,但那也同时代表着我们需要在 dataStore 模块的实现改动了以后经常维护这样的测试模板。更好的做法如下:
JavaScript
function newDataStore() {
var data = [];
return {
push: function (item) {
data.push(item);
},
pop: function() {
return data.pop();
},
length: function() {
return data.length;
}
};
}
var dataStore = newDataStore();
function newDataStore() {
var data = [];
return {
push: function (item) {
data.push(item);
},
pop: function() {
return data.pop();
},
length: function() {
return data.length;
}
};
}
var dataStore = newDataStore();
现在,测试套件看起来如下:
JavaScript
module("dataStore");
test("pop", function() {
var dataStore = newDataStore();
dataStore.push("foo");
dataStore.push("bar")
equal(dataStore.pop(), "bar", "popping returns the most-recently pushed item");
});
test("length", function() {
var dataStore = newDataStore();
dataStore.push("foo");
equal(dataStore.length(), 1, "adding 1 item makes the length 1");
});
module("dataStore");
test("pop", function() {
var dataStore = newDataStore();
dataStore.push("foo");
dataStore.push("bar")
equal(dataStore.pop(), "bar", "popping returns the most-recently pushed item");
});
test("length", function() {
var dataStore = newDataStore();
dataStore.push("foo");
equal(dataStore.length(), 1, "adding 1 item makes the length 1");
});
这让我们的全局 dataStore 和以前的行为保持一致,同时避免了测试之间的相互污染。每项测试都有自己的DataStore 实例对象,都会在测试完成时进入垃圾回收。
避免基于闭包的私有形式
我过去所推崇的另一个模式是 在 JavaScript 中建立真正的私有成员。这样做的好处是,可以保持全局可访问的命名空间免受不必要的,私有实现引用细节的侵扰。然而过度使用这种模式会导致代码无法测试。这是因为你的测试套件将无法访问到闭包中隐藏的私有函数,也无法进行测试了。考虑以下的代码:
JavaScript
function Templater() {
function supplant(str, params) {
for (var prop in params) {
str.split("{" + prop +"}").join(params[prop]);
}
return str;
}
var templates = {};
this.defineTemplate = function(name, template) {
templates[name] = template;
};
this.render = function(name, params) {
if (typeof templates[name] !== "string") {
throw "Template " + name + " not found!";
}
return supplant(templates[name], params);
};
}
function Templater() {
function supplant(str, params) {
for (var prop in params) {
str.split("{" + prop +"}").join(params[prop]);
}
return str;
}
var templates = {};
this.defineTemplate = function(name, template) {
templates[name] = template;
};
this.render = function(name, params) {
if (typeof templates[name] !== "string") {
throw "Template " + name + " not found!";
}
return supplant(templates[name], params);
};
}
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。

sales@spasvo.com