2017-05-06 30 views
1

我根据这篇文章,但有一些改进,建立与jQuery的web控件:http://alexmarandon.com/articles/web_widget_jquery/QUnit测试失败时,文件准备块声明中被测试的功能(IIFE)

现在我开始写一些测试但他们失败了,我相信这与我在上面的链接中建议的在函数内部声明一个文档就绪块有关。

这里是小工具的一个精简版:

var MyWidget = (function(w, d, $, undefined){ 

    var _getContent = function() { 
     return 'My Widget Content'; 
    } 

    var render = function(){ 
     $(function(){ 
      var content = _getContent(); 
      $('#container').html(content); 
     }); 
    } 

    return { 
     render: render 
    } 

})(window, document, jQuery, undefined); 

下面是测试:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width"> 
    <title>MyWidget Tests</title> 
    <link rel="stylesheet" href="../bower_components/qunit/qunit/qunit.css"> 
</head> 
<body> 
    <div id="qunit"></div> 
    <div id="qunit-fixture"> 
     <div id="container"></div> 
    </div> 

    <script src="../bower_components/jquery/dist/jquery.min.js"></script> 
    <script src="../bower_components/qunit/qunit/qunit.js"></script> 
    <script src="mywidget.js"></script> 

    <script> 
     QUnit.test('Test Content', function(assert){ 
      MyWidget.render(); 

      assert.equal($('#container').html(), 'My Widget Content'); 
     }); 
    </script> 
</body> 
</html> 

这里是结果:

enter image description here

然而,当我删除$(function(){的代码,然后测试通过秒。

任何想法发生了什么?

谢谢!

+1

好了,我的第一个猜测是,jQuery的周围DOMCont [包装entLoaded](https://api.jquery.com/ready/)以某种方式不被触发,因为事件已经发生,QUnit以某种方式阻止事件处理程序的延迟执行。棘手的事情...应该很容易在你的小工具之外进行测试。尽管可能是QUnit中的一个错误。我会看看我是否可以在您的小部件之外重现。 – jakerella

+0

如果你这样做,你会做不同吗? – goathi

+0

我可能不会在我的小部件中做一个'ready'函数。我会依靠代码来使用我的小工具来完成“准备好”的工作。想象一下,你有一个有30个小工具的应用程序......他们都需要自己的'ready'事件处理程序吗?可能不会。 – jakerella

回答

1

好的,我找出了问题所在。我应该早点看到它。即使后您的render函数被调用文档准备好(由于测试底部调用它),它是还是因为ready处理程序使用($(function() {})的异步。因此,您必须使测试异步。此外,您必须(a)在您的小部件中创建一些机制来通知调用代码它已完成(如PromisejQuery's Deferred);或(b)您将需要在您的测试中使用ready处理程序。下面是与你的源代码工作的测试(和JSBin to see it):

QUnit.test('Test Content', function(assert){ 
    var done = assert.async(); 
    MyWidget.render(); 
    $(function() { 
    assert.equal($('#container').html(), 'My Widget Content'); 
    done(); 
    }); 
}); 

如果你想去jQuery的递延路线,你可以做这样的事情在你的render来源:

var render = function(){ 
    var defObj = jQuery.Deferred(); 
    $(function(){ 
     var content = _getContent(); 
     $('#container').html(content); 
     defObj.resolve(); 
    }); 
    return defObj; 
} 

然后在您的测试,你会基本上是做什么我都在测试上面的例子中,只有与无极处理程序:

QUnit.test('Test Content', function(assert){ 
    var done = assert.async(); 
    MyWidget.render() 
    .then(function() { 
     assert.equal($('#container').html(), 'My Widget Content'); 
     done(); 
    }) 
    .fail(done); 
    }); 
}); 
+0

感谢您花时间研究并提供解决方案。它现在完全有道理,虽然不是那么高雅,但我会选择第一个选项,因为它是其他两个中最简单的。谢谢! – goathi