15

$(document).readyで実行するように設定されたjqueryバインディングでは、フィクスチャhtmlを使用できないことが問題であると確信しています。したがって、jquery関数を介してDOMに変更を加えることを目的としたイベントが発生しても、何も起こらず、テストは失敗します。私はここでこの問題の「解決策」を見ました、しかし私のために働いたその解決策は、.clickメソッドの代わりに.liveメソッドでバインドするように私の動作中のjquery関数を変更する必要がありました。これには2つの問題があります。まず、テストが正しく合格するように、作業コードを変更する必要はありません。テストフレームワークは、コードがアプリで機能するかどうかをテストする必要があります。アプリでは、DOMの読み込みとJavaScriptのバインドが正しい順序で行われます。私が解決策で抱えている2番目の問題は、.onと.delegateの両方が何らかの理由で機能せず、機能することになった唯一のことは、現在非推奨になっている.liveメソッドを使用することでした。結論として、$(document).readyで実行される関数の前にフィクスチャがロードされるように、テストまたはテストフレームワーク自体を変更する方法を理解したいと思います。

私はRails3.2.8を使用しており、ジャスミンテストを実験するために2つの異なるブランチを設定しています。ブランチの1つはジャスミネリスの宝石を使用し、もう1つはジャスミンレールの宝石を使用します。JavascriptとjQuery(.liveメソッドを使用する場合)のテストはすべて、これらのセットアップの両方で適切に合格します。

jasminericeを使用したブランチの説明は次のとおりです。

ジャスミンとjQueryのセットアップを説明するGemfile.lockファイルの行は次のとおりです。

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メソッドを提供します。

spec / javascriptsディレクトリ内に直接あるテストファイル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);
    });

});

app / Assets / javascriptsディレクトリにある私のjavascriptファイルtests.jsには、次の内容が含まれています。

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');
    });

});

同じapp/Assets / javascriptsディレクトリにある私のapplication.jsファイルには、次の内容が含まれています。

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require vendor
//= require_tree . 

そして、ジャスミンレールブランチの説明は、私の最初のジャスミンテスト関連のスタックオーバーフローの質問の内容にあります。

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

4

6 に答える 6

6

jQuery を html フィクスチャに直接追加すると、目的の動作が得られました。これはこの質問に対する正確な答えではありませんが、現在利用できる最善の解決策であると私は信じ始めています。私の変更は jasmine-rails gem セットアップで行われましたが、jasminerice ブランチではまだ試していません。

ここに私のテストファイルがあります:

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>
于 2012-10-10T00:49:55.970 に答える
1

個人的には、これはバグjasmine-jqueryだと思います。フィクスチャをSpecRunner.htmlの一部にすることで、これを「解決」しました。理想的ではありませんが、単純なケースで機能します。

于 2012-10-06T03:40:07.973 に答える
1

この質問が出されてからしばらく経ちました (そして回答が受け入れられました)。

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

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

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

js/test-link.js

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

specs/link-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>
于 2015-04-25T13:11:58.143 に答える
1

私はdom_mungerを使用してフィクスチャを自動的に生成したので、jquery コードをフィクスチャ内に手動で追加することはできません。私は同じ答えを探していましたが、今考えられる最善の解決策は、jQuery でイベント デリゲートを使用することです。

たとえば、次のように書く代わりに:

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

これを行う:

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

このようにして、フィクスチャがロードされる前に存在するドキュメントにリスナーがアタッチされます。そのため、クリック イベントが #target で発生すると、ドキュメントにバブル アップします。ドキュメントは、オリジンが 2 番目の引数「#target」と一致するかどうかを確認します。一致する場合、ハンドラ関数が呼び出されます。

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

于 2014-03-19T08:41:08.420 に答える
1

jasmine-jquery を試しましたか?

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

それのgithubページから、

jasmine-jquery は、Jasmine JavaScript テスト フレームワークに 2 つの拡張機能を提供します。

jQuery フレームワーク用のカスタム マッチャーのセット 仕様内の HTML、CSS、および JSON フィクスチャを処理するための API

于 2013-11-08T11:51:20.513 に答える
1

この制限を解決するために、ここで説明したものとは少し異なるアプローチを取りました。

免責事項: 私は Microsoft で働いているため、法的承認なしに実際のソース コードをここに投稿することはできません。代わりに、うまく機能するアプローチについて説明します。

動作を変更しようとするのではなくdocument.ready、jasmine-jquery ソースを変更してfixturesReady、コールバックを受け取る関数が呼び出されるようにしました。

基本的に、これは 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.beforeEachjasmine プラグインを使用している場合は、次のようにすることができます。

async.beforeEach(function(done){

    fixturesReady(done);

    ...

    loadFixtures("....");

});

この問題を解決するためのアイデアを提供してくれることを願っています。

注: プラグインで、afterEach必要に応じてブロック内のコールバックをクリアすることを忘れないでください :)

于 2014-04-14T13:40:49.463 に答える