1

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 に追加され、#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> 

http://starter.pixelgraphics.us/から生成された jQuery プラグイン コードに基づいて、JQuery コードを別のファイルに外部化しました。

(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"

この方法で書かれたプラグインをテストすることは可能ですか?

テストしやすくするために別の方法でコードを書いた方がよいでしょうか?

4

1 に答える 1

0

ここにはいくつかの問題があります。まず、コードのテストとクエリコードのテスト機能を組み合わせます。したがってexpect(result).toBeEmpty();、この $('#log').empty()コードが呼び出されたことをテストします。これはテストするのが正しいですが、要素が空であることもテストします。これはここでの作業ではありません。

次に、テストしたいコードに新しいインスタンスを作成します。これにより、テストが困難になります$。したがって、結局のところ、関数をテストして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要素の代わりにいくつかのモックを渡すことができます。モックの作成方法と使用方法については、 sinonをご覧ください。JavaScriptの世界にいるので、JQueryをモックすることもできます。テスト側にjqueryを挿入しないでください。ただし、モックで置き換えてください。

于 2011-12-24T20:53:53.057 に答える