如何用Jasmine测试JQuery插件?
问题描述:
用Jasmine对JQuery代码进行单元测试的最佳方法是什么?如何用Jasmine测试JQuery插件?
我有这个简单的jQuery的测试程序:
<div id='log'>log goes here</div>
<button id='btnClearLog'>Clear log</button>
<button id='btnAddLog'>Add log</button>
<script>
$(document).ready(function() {
$('#log').empty();
$('#btnClearLog').click(function() {
$('#log').empty();
});
$('#btnAddLog').click(function() {
$('#log').append("<br />something");
});
});
</script>
可正常工作 - DIV#日志为空文件时的负荷,增加点击时#log和明确#log。
但我不认为这是可能的单元测试,因为JQuery代码是在HTML页面内。
所以,我重新写这样的:
<div id='log'>log goes here</div>
<button id='btnClearLog'>Clear log</button>
<button id='btnAddLog'>Add log</button>
<script>
$(document).ready(function() {
$('#log').tester();
});
</script>
,并外在jQuery代码到一个单独的文件 - 像这样 - 基于生成的jQuery插件代码http://starter.pixelgraphics.us/
(function($){
$.Tester = function(el){
var base = this;
base.init = function(){
$('#log').empty();
$('#btnClearLog').click(function() {
base.clear();
});
$('#btnAddLog').click(function() {
base.add();
});
};
base.clear = function(){
$('#log').empty();
};
base.add = function(){
$('#log').append("<br />something");
};
base.init();
};
$.fn.tester = function(){
return this.each(function(){
(new $.Tester(this));
});
};
})(jQuery);
这也符合预期。
但是,我试图在Jasmine脚本不起作用。
describe('tester', function() {
it('log should be empty', function() {
var log = "<div id='log'>log</div>";
var result = $(log).tester();
expect(result).toBeEmpty();
}
});
我已经试过以上的各种排列 - 所有失败:
"Expected '<div id="log">log</div>' to be empty"
是否有可能测试这种写法的插件吗?
以另一种方式编写代码以使其更易于测试是否更好?
答
这里有一些问题。首先,将测试代码与查询代码的测试功能混合使用。因此,expect(result).toBeEmpty();
将测试这段代码被调用,这是正确的测试,但它也测试元素是空的,这不是你的工作。
其次,你在你想要测试的代码中创建新的实例,是什么让它很难测试,因为你已经处理了$
。所以,毕竟这将是只有更好,以测试你的Tester()
功能和插入的所有元素对想:
(function($){
$.Tester = function(el, log, btnClearLog, btnAddLog){
var base = this;
base.init = function(){
log.empty();
btnClearLog.click(function() {
base.clear();
});
btnAddLog.click(function() {
base.add();
});
};
base.clear = function(){
log.empty();
};
base.add = function(){
log.append("<br />something");
};
base.init();
};
$.fn.tester = function(){
return this.each(function(){
(new $.Tester(this, $('#log'), $('#btnClearLog'), $('#btnAddLog')));
});
};
})(jQuery);
这样做,所以你可以测试只有你测试仪,通过在一些嘲笑,而不是真正的DOM元素。看看如何创建和使用mock的sinon。正如我们在JavaScript世界中一样,你也可以嘲笑JQuery,简单地说不要将jquery插入你的测试端,而是通过模拟替代它。