编写可测试的JavaScript代码
作者:网络转载 发布时间:[ 2016/6/2 15:03:04 ] 推荐标签:Javascript web测试
Twitter 的工程师文化要求进行测试,许多的测试。在进入 Twitter 之前我还未有过测试 JavaScript 的经验,所以在这之后我学习到了很多。特别是学到了许多过去我使用、书写和鼓励使用的代码其实是不利于书写可测试的代码的。所以我觉得在此分享我所学习到有价值的,如何书写可测试的 JavaScript 几条重要的原则。这里提供的这些示例虽然基于 QUnit,但是也应该适用于其他的 JavaScript 测试框架。
避免单例
我受欢迎的博文中的其中一篇是关于如何使用 《JavaScript 模块模式》 在程序中创建强大的单例。这种做法简单有效,但是给测试带来了问题。理由很简单: 单例在测试间造成了状态污染 。与其把单例当作模块使用,不如把他们写成可构造的对象。一旦应用程序初始化,在全局层上分配一个单一的、默认的实例。
例如,考虑如下的单例模块(当然,是人为的例子):
JavaScript
var dataStore = (function() {
var data = [];
return {
push: function (item) {
data.push(item);
},
pop: function() {
return data.pop();
},
length: function() {
return data.length;
}
};
}());
var dataStore = (function() {
var data = [];
return {
push: function (item) {
data.push(item);
},
pop: function() {
return data.pop();
},
length: function() {
return data.length;
}
};
}());
有了这个模块,我们可能想测试 foo.bar 方法。以下是一个简单的 QUnit 测试套件:
JavaScript
module("dataStore");
test("pop", function() {
dataStore.push("foo");
dataStore.push("bar")
equal(dataStore.pop(), "bar", "popping returns the most-recently pushed item");
});
test("length", function() {
dataStore.push("foo");
equal(dataStore.length(), 1, "adding 1 item makes the length 1");
});
module("dataStore");
test("pop", function() {
dataStore.push("foo");
dataStore.push("bar")
equal(dataStore.pop(), "bar", "popping returns the most-recently pushed item");
});
test("length", function() {
dataStore.push("foo");
equal(dataStore.length(), 1, "adding 1 item makes the length 1");
});

sales@spasvo.com