2013-06-01 109 views
28

你如何去使用和修改DOM的单元测试JavaScript?单元测试涉及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'); 
} 

什么是试图单元测试这样的事情最好的做法?

+1

看看PhantomJS。 http://phantomjs.org/ – Brad

+0

另请参见[在茉莉花测试中测试DOM操作](http://stackoverflow.com/questions/7672389/testing-dom-manipulating-in-jasmine-test) –

+0

。和CasperJs:http ://casperjs.org/ – kaore

回答

19

理想情况下,你应该分裂的代码。验证逻辑并不需要DOM访问,所以你可以将它放入它自己的函数中,并将处理ID的逻辑放入一个值中,然后再将其验证到另一个值中。

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

+1

这绝对是一种方式。与DOM交互通常意味着您正在执行更多功能或集成测试。使用自己的单元测试将验证代码放入单独的模块中。然后使用您最喜欢的模块加载器,如browserify https://github.com/substack/browserify – Noah

9

您可以使用Qunit进行涉及DOM的单元测试。如果你想自动化,你可以使用Gruntgrunt-contrib-qunit任务,这个任务在一个名为PhantomJS的无头Webkit中启动你的页面。

+2

这里是一个如何做到这一点的示例:http://stackoverflow.com/a/4178173/507339 – Nilzor

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