单元测试涉及DOM的Javascript

时间:2013-06-01 03:39:57

标签: javascript unit-testing

你如何进行单元测试使用和修改DOM的javascript?

我举一个简单的例子。一个表单验证器,用于检查用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;
       };
    }

用法:

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');
}

尝试对此类单元进行单元测试的最佳做法是什么?

3 个答案:

答案 0 :(得分:19)

理想情况下,您应该拆分代码。验证逻辑实际上并不需要DOM访问,因此您可以将其放入其自己的函数中,并将处理该ID的逻辑放入一个值,然后将该值验证到另一个值中。

通过这样做,您可以更轻松地对验证逻辑进行单元测试,并在必要时使用Joseph the Dreamer建议的一些工具对整个事物进行功能测试。

答案 1 :(得分:10)

您可以使用Qunit进行涉及DOM的单元测试。如果您希望自动化,则可以Grunt使用grunt-contrib-qunit任务,该任务会在名为PhantomJS的无头WebKit中启动您的网页。

答案 2 :(得分:9)

在大多数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;
    }....
}

在测试中提供模拟实现:

 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");
 }