2012-10-03 13 views
15

$(document).readyで実行するように設定されたjqueryバインディングが、使用可能なフィクスチャhtmlを持っていないということはかなり確信しています。したがって、jquery関数を介してDOMに変更を加えるためのイベントが発生した場合、何も起こらず、テストが失敗します。私はこの問題の "解決策"を見たhereしかし、私のために働いた解決策は、.clickメソッドの代わりに.liveメソッドでバインドするために私の作業jquery関数を変更する必要がありました。私はこれに2つの問題があります。まず、テストが適切に行われるように作業コードを変更する必要はありません。テストフレームワークは、DOMロードとjavascriptバインディングが正しい順序で行われるアプリでコードが動作するかどうかをテストする必要があります。私が解決策に持っている2番目の問題は、.onと.delegateが両方とも何らかの理由で動作しなかったことです。動作しなくなったのは、現在廃止されつつある.liveメソッドを使用することだけでした。結論として、私は、フィクスチャが$(document).readyで動作する関数の前にロードされるように、テストまたはテストフレームワーク自体を変更する方法を理解したいと思います。ジャスミンテストのフィクスチャをロードするにはどうすればよいですか?

私はレール3.2.8で作業しています。ジャスミンテストを試すために2つの異なるブランチを設定しました。支店の1つはジャスミンネリセの宝石を使い、もう1つはジャスミンレールの宝石を使います。 JavascriptとjQuery(.liveメソッドを使用している場合)のテストは、これらの設定の両方で正しくパスします。ここで

はjasminericeを使用して、分岐の説明である:ここで

はジャスミンを記述する私のGemfile.lockファイルからの行があるとjQueryはセットアップ:

jasminerice (0.0.9) 
    coffee-rails 
    haml 
jquery-rails (2.1.3) 
    railties (>= 3.1.0, < 5.0) 
    thor (~> 0.14) 

Jasminericeはによってjasmine-jquery拡張子を含みますデフォルト。 jasmine-jQuery拡張機能は、テストで使用しているtoHaveTextメソッドを提供します。

直接指定/ JavaScriptのディレクトリ内にあるテストファイルjasmine_jquery_test.jsは、このコンテンツを含んでいます

#= require application 

describe ("my basic jasmine jquery test", function(){ 

    beforeEach(function(){ 
     $('<a id="test_link" href="somewhere.html">My test link</a>').appendTo('body'); 
    }); 

    afterEach(function(){ 
     $('a#test_link').remove(); 
    }); 

    it ("does some basic jQuery thing", function() { 
     $('a#test_link').click(); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

    it ("does some the same basic jQuery thing with a different trigger type", function() { 
     $('a#test_link').trigger('click'); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

}); 
describe ('subtraction', function(){ 

    var a = 1; 
    var b = 2; 

    it("returns the correct answer", function(){ 
     expect(subtraction(a,b)).toBe(-1); 
    }); 

}); 

dirがこれを持っているアプリ/資産/ JavaScriptの中に位置しています私のjavascriptのファイルtests.js内容:

//= require jquery 
//= require jquery_ujs 
//= require bootstrap 
//= require vendor 
//= require_tree . 
:同じアプリ/資産/ JavaScriptのdirをに位置

function subtraction(a,b){ 
    return a - b; 
} 

jQuery (function($) { 
/* 
    The function I would rather use - 
    $("a#test_link").click(changeTheTextOfTheLink) 
    function changeTheTextOfTheLink(e) { 
     e.preventDefault() 
     $("a#test_link").append(' is now longer'); 
    } 
*/ 

    $("a#test_link").live('click', function(e) { 
     e.preventDefault(); 
     $("a#test_link").append(' is now longer'); 
    }); 

}); 

私application.jsファイルには、このコンテンツを持っています

ジャスミンレールの説明は、first jasmine test related stackoverflow questionの内容に記載されています。

したがって、フィクスチャがロードされた後に$(document).ready関数が実行されるようにテストを操作する方法があれば、私はあなたの考えを聞きたいと思いますか?

答えて

6

htmlフィクスチャにjQueryを直接追加することで、目的の動作を得ることができました。この質問に対する答えは正確ではありませんが、現在入手可能な最良のソリューションだと考え始めています。私の変更は、ジャスミンレールの宝石のセッティングで行われましたが、私はまだジャスミンミセス支店でそれを試していません。

describe ("my basic jasmine jquery test", function(){ 

    beforeEach(function(){ 
     loadFixtures('myfixture.html'); 
    }); 

    it ("does some basic jQuery thing", function() { 
     $('a#test_link').click(); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

    it ("does the same basic jQuery thing with a different event initiation method", function() { 
     $('a#test_link').trigger('click'); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

}); 
describe ('substraction', function(){ 

    var a = 1; 
    var b = 2; 

    it("returns the correct answer", function(){ 
     expect(substraction(a,b)).toBe(-1); 
    }); 

}); 

そして、ここでは私のフィクスチャファイルです:

<a id="test_link" href="somewhere.html">My test link</a> 

<script> 
    $("a#test_link").click(changeTheTextOfTheLink) 
    function changeTheTextOfTheLink(e) { 
     e.preventDefault() 
     $("a#test_link").append(' is now longer'); 
    } 
</script> 
+1

ドキュメンテーションの[jasmine-jquery](https://github.com/velesin/jasmine-jquery)に記載されているとおり、デフォルトでは、フィクスチャはspec/javascripts/fixturesから読み込まれます。このパスを設定することができます:jasmine.getFixtures()。fixturesPath = 'my/new/path'; ' – RamRovi

+0

これはまだ最高の解決策ですか?現時点では、プロダクションコードを変更するたびにフィクスチャにコピーする必要があるため、これは面倒です! – james

1

個人的には、私はこれをバグジャスミンjqueryとみなします。私はSpecRunner.htmlの一部に私の器具を作ることでこれを "解決"しました。理想的ではありませんが、単純なケースでは機能します。

+2

RailsアプリでJasmineを使用していますか?もしそうなら、あなたの設定を説明できますか?基本的に、私が知る限り、私はSpecRunner.htmlファイルを使用していません。しかし、おそらく私の什器にjQuery関数を追加するのと同じ方法で動作します...試みます。 –

1

あなたはジャスミン-jqueryのを試してみましたが、ここで

は私のテストファイルはありますか?

jQueryのフレームワーク HTMLを扱うためのAPIのカスタムマッチャのセット:それから

https://github.com/velesin/jasmine-jquery

ジャスミン-jqueryのは、ジャスミンのJavaScriptテストフレームワークのための2つの拡張機能を提供し、githubのページです、CSS、およびJSONの各フィクスチャーをご用意しております。

1

sed dom_munger私のために自動的に照明器具を生成するので、照明器具の中に手動でjqueryコードを追加することは私の選択肢ではありません。私は同じ答えを探していましたが、私が考えることができる最良の解決策は、jQueryでイベントデリゲートを使用することです。

$('#target').click(function(){ 
    // Do work 
}); 

がこれを行います:代わりにこれを書いている。例えば

$(document).on('click', '#target', function(){ 
    // Do work 
}); 

をこのように、リスナーは、フィクスチャがロードされる前に存在している文書に取り付けられています。だから、クリックイベントが#targetで起きると、それはドキュメントにバブルアップします。ドキュメントは、原点が第2引数 - ##targetと一致するかどうかをチェックします。一致する場合は、ハンドラ関数が呼び出されます。

プラグインの初期化など、これには制限がありますが、問題の一部が解決されることは知っています。

+0

パフォーマンスの悪夢はスケールされません。あなたのテストフレームワークがあなたのコードに悪影響を与えるようにしています。 – sarink

+0

パフォーマンスの悪夢? $( "#parent-of-target")をon( "click"、 "#target"、function(){})するだけです。 –

1

この制限を解決するために、ここで説明した方法とは多少異なる方法を採用しました。

免責事項:マイクロソフトで働いていますので、実際のソースコードを法的な承認なしにここに掲載することはできません。代わりに、うまくいくアプローチを説明します。

document.readyの動作方法を変更するのではなく、コールバックを取るfixturesReadyという関数をサポートするようにjasmine-jqueryソースを変更しました。

これは基本的にIIFEの内部で定義され、トリガー時に反復されるイベント名ごとのコールバックの配列を保持します。今、あなたが反対コーディングすることができ、あなたのテストでそう

jasmine.Fixtures.prototype.load = function() { 
    this.cleanUp() 
    this.createContainer_(this.read.apply(this, arguments)) 

    fixturesReady.trigger("loaded", arguments); // <----- ADD THIS 

} 

次に、このチャンクにあなたはトリガーを置くことができ

fixturesReady(yourCallback) 

そして、あなたが知っているyourCallbackが呼び出されたときに、あなたが安全に問い合わせることができていますあなたのフィクスチャー要素のDOM。さらに

、あなたはこれを行うことができますプラグインasync.beforeEachジャスミンを使用している場合:

async.beforeEach(function(done){ 

    fixturesReady(done); 

    ... 

    loadFixtures("...."); 

}); 

希望に役立ち、あなたにこの問題を解決についていくつかのアイデアを与えるのに役立ちます。

注:この質問は頼まれた(そして答えは受け入れられる)ので、それはしばらくしている

1

:)必要に応じてafterEachブロック内の任意のコールバックをクリアするためにあなたのプラグインに覚えておいてください。

ここでは、テストを構成し、ジャスミンでテストするためのスクリプトをロードするためのより良いアプローチです。

テンプレート/ link.tmpl.html

<a id="test_link" href="somewhere.html">My test link</a> 

JS /テストlink.js

$("a#test_link").click(changeTheTextOfTheLink) 
function changeTheTextOfTheLink(e) { 
    e.preventDefault() 
    $("a#test_link").append(' is now longer'); 
} 

スペック/リンクtest.spec.js

describe ("my basic jasmine jquery test", function(){ 

    jasmine.getFixtures().fixturesPath = '' 

    var loadScript = function(path) { 
     appendSetFixtures('<script src="' + path + '"></script>'); 
    }; 

    beforeEach(function(){ 
     loadFixtures('templates/link.tmpl.html'); 
     loadScript('js/test-link.js'); 
    }); 

    it ("does some basic jQuery thing", function() { 
     $('a#test_link').click(); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

    it ("does the same basic jQuery thing with a different event initiation method", function() { 
     $('a#test_link').trigger('click'); 
     expect($("a#test_link")).toHaveText('My test link is now longer'); 
    }); 

}); 

スペックランナー

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
    <title>Spec Runner</title> 

    <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.3/jasmine.css"> 
    <script type="text/javascript" src="lib/jasmine-2.0.3/jasmine.js"></script> 
    <script type="text/javascript" src="lib/jasmine-2.0.3/jasmine-html.js"></script> 
    <script src="lib/jasmine-2.2/boot.js"></script> 

    <script type="text/javascript" src="lib/jquery-2.1.3.min.js"></script> 
    <script type="text/javascript" src="lib/jasmine-jquery.js"></script> 

    <script type="text/javascript" src="specs/link-test.spec.js"></script> 
</head> 

<body> 
</body> 
</html> 
関連する問題