2017-08-15 3 views
0

Jasmineを使用すると、ブラウザでコードが正常に動作していますが、正しく動作しません。これはユニットテストの設定に失敗します。jquery/jasmineでボタンハンドラが呼び出されない

ボタンが付いたフォームがあります。

<div class="templates"> 
      <div class="problem-view"> 
       <h3 class="title"></h3> 
       <p data-name="description"></p> 
       <pre><code data-name="code"></code></pre> 
       <form> 
        <textarea class='u-full-width answer'></textarea> 
        <div> 
         <button class='button-primary check-btn'>Check Answer</button> 
         <p class='result'></p> 
        </div> 
       </form> 
      </div> 
     </div>  
     </div> 

私はジャスミンから関数内app.jsに

learnjs.problemView = function(data) { 
    var view = $('.templates .problem-view').clone(); 
    function checkAnswerClick(){ 
     console.log('checking answer'); 
     if(checkAnswer()){ 
      console.log('setting to correct'); 
      resultFlash.text('Correct!');   
     }else{ 
      console.log('setting to incorrect'); 
      resultFlash.text('Incorrect!'); 
     } 
     return false; 
    } 
    console.log('inside pv') 
    var b = view.find('.check-btn'); 
    b.click(checkAnswerClick); 
} 

をボタンのハンドラを設定している、私はそのクリックメソッドを呼び出していますが、それは作業を取得されていません。コンソールプリントが表示されませんconsole.log('checking answer');ブラウザでエラーが表示されますExpected '' to equal 'Correct!'。これは、<p>CorrectまたはIncorrectに設定する必要があるためですが、空です。

describe ('answer section',function() { 
    it('can check correct answer by hitting a button', function(){ 
     var v1 = view1.find('.answer').val('true'); 
     console.log('clicking'); 
     var b1 = view1.find('.check-btn'); 
     var b2=$("#b") 
     console.log("events: b:"+b2.html()+","+$._data($("#b"),"events")); 
     b1.click(); 
     console.log('v1 is '+v1.val()); 
     console.log('b1 is '+b1.html()); 
     var r =view1.find('.result'); 
     console.log('r is '+r.text()); 
     spyOn(learnjs,'checkAnswerClick'); 
     expect(view1.find('.result').text()).toEqual('Correct!'); 
     expect(learnjs.problemView.checkAnswerClick).toHaveBeenCalled(); 
    }); 

は、ブラウザ上でより多くの説明

を追加しました、使用されるファイルには、index.htmlを/公共および公共/ app.jsです。 Jasmineはpublic/test/index.htmlにpublic/index.htmlの内容をコピーするSpecHelper.jsというヘルパー関数を持っています(まだこのことを学んでいます)。

SpecHelper.js

var fixture; 
var view1; 

function loadFixture(path) { 
    var html; 
    var test; 
    jQuery.ajax({ 
    url: '/index.html', 
    success: function(result) { 
     html = result; 
    }, 
    async: false 
    });   
    return $.parseHTML(html); 
} 

function resetFixture() { 
    if (!fixture) { 
    var index = $('<div>').append(loadFixture('/index.html')); 
    var markup = index.find('div.markup'); 
    console.log("markup :"+markup.html()) 
    fixture = $('<div class="fixture" style="display: none">').append(markup); 
    console.log("fixture is "+fixture.html()); 
    $('body').append(fixture.clone(true, true)); 
    } else { 
    //console.log("3. fixture is "+fixture); 
    $('.fixture').replaceWith(fixture.clone(true, true)); 
    } 

} 

beforeEach(function() { 
    resetFixture(); 
    view1 = $('.templates .problem-view').clone(true, true); 
    console.log("view1:"+view1.html()); 
}); 

公開/テスト/ index.htmlには好き、これを探します。基本的には、このindex.htmlをのボディはSpecHelper.jsにbeforeEach(上記に定義)にresetFixtureへの呼び出しによって変更されます

<!DOCTYPE HTML> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <title>Jasmine Spec Runner v2.3.4</title> 

    <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.3.4/jasmine_favicon.png"> 
    <link rel="stylesheet" type="text/css" href="lib/jasmine-2.3.4/jasmine.css"> 

    <!-- App Dependencies --> 
    <script src="lib/jquery-2.1.4.js"></script> 
    <script src="/vendor.js"></script> 

    <!-- Test libraries --> 
    <script type="text/javascript" src="lib/jasmine-2.3.4/jasmine.js"></script> 
    <script type="text/javascript" src="lib/jasmine-2.3.4/jasmine-html.js"></script> 
    <script type="text/javascript" src="lib/jasmine-2.3.4/boot.js"></script> 

    <!-- include source files here... --> 
    <script type="text/javascript" src="/app.js"></script> 

    <!-- include spec files here... --> 
    <script type="text/javascript" src="SpecHelper.js"></script> 
    <script type="text/javascript" src="app_spec.js"></script> 
</head> 

<body> 
</body> 
</html> 

したがって、各スペックを実行する前に、パブリック/ index.htmlをからの内容は、にコピーします必要がありますpublic/test/index.htmlを開き、新しいビューを作成する必要があります。仕様は、Jasmineがテストケースを実行するために使用するapp_spec.jsで定義されています。テストケースの1つが上で説明されています

私は現在、クローン(true、true)を使用しているため、view1はイベントハンドラとともにfixtureからクローンされるはずです。このビュー1はapp_spec.jsおよびb1 .clickは動作するはずexpect(learnjs.problemView.checkAnswerClick).toHaveBeenCalled();もクリックのコールバックが呼び出さ取得されていないことを示すブラウザで

エラー失敗することに注意してください:。。!。期待

  1. 「正しい」と等しくなるように「」
  2. スパイを期待、しかし、定義されていない。< - 多分私はスパイを使用しています正しく

これは問題を解決した新しいdescribeです。以下のコメントを参照してください。

私はあなたがいない場合 <form></form>意志自動で <button></button>type='submit'を設定しているので、あなたのHTMLコード

<button class='button-primary check-btn' type='button'>Check Answer</button>

<button class='button-primary check-btn'>Check Answer</button>

を変更しようとすることができると思い

describe('problem view', function() { 
     var view1; 
     beforeEach(function() { 
      view1 = learnjs.problemView('1'); //this is where I am registering the click event callback. I had to call this. I wasn't doing so earlier 
     }); 

     describe ('answer section',function() { 

      it('can check correct answer by hitting a button', function(){ 
       console.log("in It - view1:"+view1.html()) 
       var v1 = view1.find('.answer').val('true'); 
       console.log('clicking'); 
       var b1 = view1.find('.check-btn'); 
       var b2=$("#b") 
       console.log("events: b:"+b2.html()+","+$._data($("#b"),"events")); 
       //b1.click(learnjs.problemView.checkAnswerClick); 
       b1.click(); 
       console.log('v1 is '+v1.val()); 
       console.log('b1 is '+b1.html()); 
       console.log("2nd events: "+$._data($("#b"),'events')); 
       var r =view1.find('.result'); 
       console.log('r is '+r.text()); 
       //spyOn(learnjs,'learnjs.problemView.checkAnswerClick'); 
       expect(view1.find('.result').text()).toEqual('Correct!'); 
       //expect(learnjs.problemView.checkAnswerClick).toHaveBeenCalled(); 
      }); 

答えて

0

type='button'を設定してください。デフォルトでページをリフレッシュします。

これは、コンソールで「アンサーの確認」が表示されない可能性があります。


私は私の地元の環境には、このコードが、

<body> 
    <div class="templates"> 
    <div class="problem-view"> 
     <h3 class="title"></h3> 
     <p data-name="description"></p> 
     <pre><code data-name="code"></code></pre> 
     <form> 
      <textarea class='u-full-width answer'></textarea> 
      <div> 
       <button class='button-primary check-btn' type="button">Check Answer</button> 
       <p class='result'></p> 
      </div> 
     </form> 
    </div> 
</div>  

     <script> 
var view = $('.templates .problem-view').clone(); 

problemView = function(data) { 
    function checkAnswerClick(){ 
     console.log('checking answer'); 
     if(checkAnswer()){ 
      console.log('setting to correct'); 
      resultFlash.text('Correct!');   
     }else{ 
      console.log('setting to incorrect'); 
      resultFlash.text('Incorrect!'); 
     } 
     return false; 
    } 

    var b = view.find('.check-btn'); 
    console.log(b) 
    b.click(checkAnswerClick); 
} 

problemView(); 

describe ('answer section',function() { 
     it('can check correct answer by hitting a button', function(){ 
      var v = view.find('.answer').val('true'); 
      console.log('clicking'); 
      var b = view.find('.check-btn').click(); 
      console.log('v is '+v.html()); 
      console.log('b is '+b.html()); 
      var r =view.find('.result'); 
      console.log('r is '+r.text()); 
      expect(view.find('.result').text()).toEqual('Correct!'); 
     }); 
}) 
</script> 
</body> 

をこのコードを試してみましたが、エラーcheckAnswer is not definedを投げるが、私は私のコンソールでchecking answerを見ることができます。 私はあなたがクリックイベントを発生させることができない理由は、problemViewで宣言した変数viewは、関数describeと同じではないと考えています。


私は問題が

var $dom1 = $('.templates .problem-view').clone(true, true); 
var $dom2 = $('.templates .problem-view').clone(true, true); 

$dom1$dom2だと思いますが、完全に2つの異なるオブジェクトです。

代わりに、このような元ドムに直接結合事象のクローン化されたDOMにあなたバインドイベント、なぜ私が理解することはできません。

learnjs.problemView = function(data) { 
    var view = $('.templates .problem-view');// remove .clone() 
    function checkAnswerClick(){ 
     console.log('checking answer'); 
     if(checkAnswer()){ 
      console.log('setting to correct'); 
      resultFlash.text('Correct!');   
     }else{ 
      console.log('setting to incorrect'); 
      resultFlash.text('Incorrect!'); 
     } 
     return false; 
    } 
    console.log('inside pv') 
    var b = view.find('.check-btn'); 
    b.click(checkAnswerClick); 
} 
+0

は動作しませんでした。とにかく、私はcheckAnswerClickでフォーム提出をfalseに設定しました。この問題は、 'b.click();'が実行されたときにcheckAnswerClickが呼び出されないことが原因です。私はすべてのクローンAPIをクローンに変更して(true、true)、すべてのイベントもコピーされますが、それも機能しません。驚くべきことに、コードはJasmineなしで動作します –

+0

@Manu Chadhaあなたのコードに関する詳細を表示できますか?あなたが定義した 'var view = $( '。templates .problem-view').clone();' 'learnjs.problemView'は' var b = view.find( '。check-btn')。click(); '私のローカルで試したところ、 'var view = $('。templates .problem -view ').clone();'関数の外にそれは仕事のようです – MinimalistYing

+0

は、より多くのコードを追加しました。混乱を避けるため、 'view'を' view1'に変更しました。私もスパイを追加しました。私は 'view'がapp_spec.jsの範囲にないことを確認しました。 –

関連する問題