在被测试的函数内声明文档就绪块时,QUnit测试失败(IIFE)

时间:2017-05-06 17:17:00

标签: javascript jquery qunit

我根据这篇文章使用jQuery构建了一个Web小部件,但有一些改进:http://alexmarandon.com/articles/web_widget_jquery/

现在我开始编写一些测试,但是它们失败了,我相信它与我在函数内声明一个文档就绪块有关,如上面的链接所示。

以下是小部件的精简版:

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 个答案:

答案 0 :(得分:1)

好的,我弄清楚问题是什么。我应该早点看到它。即使你的render函数在文档准备好之后被调用(因为测试在底部调用它),它仍然是仍然异步,因为{您使用的{1}}处理程序(ready)。因此,您必须使您的测试异步。此外,您必须(a)在窗口小部件中创建一些机制,以通知调用代码它是完整的(如PromisejQuery's Deferred);或者(b)您需要在测试中使用$(function() {}处理程序。这是一个适用于源代码的测试(和JSBin to see it):

ready

如果您想使用jQuery Deferred路由,可以在QUnit.test('Test Content', function(assert){ var done = assert.async(); MyWidget.render(); $(function() { assert.equal($('#container').html(), 'My Widget Content'); done(); }); }); 来源中执行以下操作:

render

然后在你的测试中你基本上会在上面的测试例子中做我所拥有的,只有Promise处理程序:

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