简体   繁体   English

单元测试涉及DOM的Javascript

[英]Unit testing Javascript that involves the DOM

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? 尝试对此类单元进行单元测试的最佳做法是什么?

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建议的一些工具对整个事物进行功能测试。

You can use Qunit for unit tests involving DOM. 您可以将Qunit用于涉及DOM的单元测试。 If you want it automated, you can use Grunt with grunt-contrib-qunit task which launches your pages in a headless WebKit called PhantomJS . 如果你想让它自动化,你可以使用Gruntgrunt-contrib-qunit任务在一个名为PhantomJS的无头WebKit中启动你的页面。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM