当在被测试函数 (IIFE) 中声明文档就绪块时,QUnit 测试失败
QUnit test fails when document-ready block is declared inside the function being tested (IIFE)
我正在基于此 post 使用 jQuery 构建一个网络小部件,但有一些改进:http://alexmarandon.com/articles/web_widget_jquery/
现在我开始编写一些测试,但它们都失败了,我相信这与我在函数内声明一个文档就绪块有关,如上面 link 中所建议的。
这是小部件的精简版:
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>
结果如下:
但是,当我删除$(function(){
代码时,测试通过。
知道发生了什么吗?
谢谢!
好的,我知道问题出在哪里了。我应该早点看到它。即使您的 render
函数在 文档准备就绪后被调用(因为测试在底部调用它),它 仍然是异步的 因为您使用 ready
处理程序 ($(function() {}
)。因此,您必须使测试异步。此外,您将不得不 (a) 在您的小部件中创建一些机制来通知调用代码它已完成(如 Promise
, or jQuery's Deferred
); or (b) you will need to also use a ready
handler in your test. Here is a test that works with your source code (and a 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;
}
然后在你的测试中,你基本上会做我在上面的测试示例中所做的,只有 Promise 处理程序:
QUnit.test('Test Content', function(assert){
var done = assert.async();
MyWidget.render()
.then(function() {
assert.equal($('#container').html(), 'My Widget Content');
done();
})
.fail(done);
});
});
我正在基于此 post 使用 jQuery 构建一个网络小部件,但有一些改进:http://alexmarandon.com/articles/web_widget_jquery/
现在我开始编写一些测试,但它们都失败了,我相信这与我在函数内声明一个文档就绪块有关,如上面 link 中所建议的。
这是小部件的精简版:
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>
结果如下:
但是,当我删除$(function(){
代码时,测试通过。
知道发生了什么吗?
谢谢!
好的,我知道问题出在哪里了。我应该早点看到它。即使您的 render
函数在 文档准备就绪后被调用(因为测试在底部调用它),它 仍然是异步的 因为您使用 ready
处理程序 ($(function() {}
)。因此,您必须使测试异步。此外,您将不得不 (a) 在您的小部件中创建一些机制来通知调用代码它已完成(如 Promise
, or jQuery's Deferred
); or (b) you will need to also use a ready
handler in your test. Here is a test that works with your source code (and a 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;
}
然后在你的测试中,你基本上会做我在上面的测试示例中所做的,只有 Promise 处理程序:
QUnit.test('Test Content', function(assert){
var done = assert.async();
MyWidget.render()
.then(function() {
assert.equal($('#container').html(), 'My Widget Content');
done();
})
.fail(done);
});
});