按钮处理程序没有在jquery / jasmine中调用

时间:2017-08-15 06:01:32

标签: jquery jasmine

我的代码在浏览器上工作正常但在我使用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);  
}

从Jasmine,我正在调用它的click方法,但它没有开始工作。我没有看到控制台打印console.log('checking answer');我在浏览器Expected '' to equal 'Correct!'中看到错误。这是因为<p>应该设置为CorrectIncorrect,但它是空的!

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

添加了更多解释

在浏览器上,将使用的文件是public / index.html和public / app.js。对于Jasmine,我有一个帮助函数,SpecHelper.js将public / index.html的内容复制到public / test / index.html,因为jasmine使用public / test / index.html我认为(仍在学习这些东西)

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

public / test / 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>

因此,在运行每个规范之前,public / index.html中的内容应该复制到public / test / index.html,然后从那里创建一个新视图。规范在app_spec.js中定义,Jasmine用它来运行测试用例。其中一个测试用例如上所述

我猜测view1应该从fixture和事件处理程序克隆(因为我现在使用clone(true,true)。这个view1在app_spec.js中可用,b1.click应该可以工作。注意{{ 1}}也失败,表示没有调用click的回调。

浏览器错误:

  1. 期望''等于'正确!'。
  2. 期待间谍,但未定义。 &lt; - 也许我错误地使用间谍
  3. 这是解决问题的新expect(learnjs.problemView.checkAnswerClick).toHaveBeenCalled();。请参阅以下评论。

    describe

1 个答案:

答案 0 :(得分:0)

我认为您可以尝试更改HTML代码

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

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

如果您未设置<button></button><form></form>中的type='submit'会自动设置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。 我认为您甚至无法触发click事件的原因是您在函数view中声明的变量problemView与您在函数describe中使用的变量var $dom1 = $('.templates .problem-view').clone(true, true); var $dom2 = $('.templates .problem-view').clone(true, true); 不同。

我认为问题是

$dom1

$dom2learnjs.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); } 完全是两个不同的对象。

我无法理解为什么你在克隆的Dom上绑定事件而不是直接在原始Dom上绑定事件,如下所示:

1.15.0