涉及 DOM 的单元测试 Javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16868821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unit testing Javascript that involves the DOM
提问by BIOS
How do you go about unit testing javascript that uses and modifies the DOM?
您如何对使用和修改 DOM 的 javascript 进行单元测试?
I'll give an easy example. A form validator that checks for blank text fields, written in javascript and that uses JQuery.
我举一个简单的例子。检查空白文本字段的表单验证器,用 javascript 编写并使用 JQuery。
function Validator() {
this.isBlank = function(id) {
if ($(id).val() == '') {
return true;
} else {
return false;
}
};
this.validate = function(inputs) {
var errors = false;
for (var field in inputs) {
if (this.isBlank(inputs[field])) {
errors = true;
break;
}
}
return errors;
};
}
Usage:
用法:
var validator = new Validator();
var fields = { field_1 : '#username', field_2 : '#email' };
if (!validator.validate(fields)) {
console.log('validation failed');
} else {
console.log('validation passed');
}
What is the best practice for attempting to unit test something like this?
尝试对此类进行单元测试的最佳做法是什么?
采纳答案by Jani Hartikainen
Ideally you should split the code. The validation logic does not really require DOM access, so you would put that into its own function, and put the logic that processes the ID into a value that is then validated into another.
理想情况下,您应该拆分代码。验证逻辑并不真正需要 DOM 访问,因此您可以将其放入其自己的函数中,并将处理 ID 的逻辑放入一个值中,然后将其验证为另一个值。
By doing this, you can more easily unit test the validation logic, and if necessary do a functional test on the whole thing using some of the tools suggested by Joseph the Dreamer.
通过这样做,您可以更轻松地对验证逻辑进行单元测试,并在必要时使用 Joseph the Dreamer 建议的一些工具对整个事物进行功能测试。
回答by Joseph
You can use Qunitfor unit tests involving DOM. If you want it automated, you can use Gruntwith grunt-contrib-qunittask which launches your pages in a headless WebKit called PhantomJS.
您可以使用Qunit进行涉及 DOM 的单元测试。如果您希望它自动化,您可以将Grunt与grunt-contrib-qunit任务一起使用,该任务在名为PhantomJS的无头 WebKit 中启动您的页面。
回答by Alexei Levenkov
In unlikely case when most of your JavaScript code contains logic and rely on small amount of jQuery code (or live DOM elements) you can refactor code to make replacing access to DOM/usage of jQuery easy and write test with mock implementations:
在不太可能的情况下,当您的大多数 JavaScript 代码包含逻辑并依赖少量 jQuery 代码(或实时 DOM 元素)时,您可以重构代码以轻松替换对 DOM 的访问/jQuery 的使用,并使用模拟实现编写测试:
function Validator(){
this.getElementValue = function(id){return $(id).val();}
this.check_blank = function(id){
if(this.getElementValue(id) == '') // replace direct call to jQuery mock-able call
return false;
else
return true;
}....
}
And in test provide mock implementation:
并在测试中提供模拟实现:
test("Basic valid field", function() {
var validation = new Validator();
// replace element accessor with mock implementation:
validation.getElementValue = function(id){
equals(id, "#my_field"); // assert that ID is expected one
return "7";
}
var form_fields = {field_1 : '#my_field'};
ok(validation.validate(form_fields), "non-empty field should be valid");
}