如何使用jasmine和sinon在函数内模拟jquery调用

时间:2013-08-09 17:24:57

标签: jquery backbone.js jasmine sinon

首先,这是一项工作要求。如果不能这样做,我需要一个好的论据来给予。

我必须使用jasmine和sinon测试我们的骨干项目。我无法弄清楚如何在函数中模拟jquery调用。我有这样的功能(清理一点以丢弃无关的呼叫):

Project.Views.FormView = Backbone.View.extend({
  sidenavClicked: function(event){



    var sidenav_id = $(event.target).attr('id').split('m')[1];
    var sidenav_num = sidenav_id.split('m')[1];

    var form_id = $('div.active form').attr('id');
    var form_num = form_id.split('m')[1];

    //code for fast scrolling
    this.slideTo(form_num-1, sidenav_num-1);

    return false;
  },
  ...
});

现在我只是试图测试slideTo()被调用这是我的茉莉花规格

describe("Form", function(){
    describe("Carousel", function(){

    it("should call slideTo when navbar is clicked", function(){
        var spy = sinon.spy();
        var formView = new Project.Views.FormView({ el : $('#main'), id : 1});
        formView.bind('slideTo', spy);

        var event = {};
        event.target = "<div id='form1'></div>";

        formView.sidenavClicked(event);
    });
});

错误消息是:TypeError:form_id在文件中未定义:... / src / main / webapp / js / views / FormView.js

据我所知,因为没有jQuery的文档可以匹配。如何让form_id获得值?

实际的代码确实有用,并且确实做了它应该做的事情。

更新:html看起来像这样:

<html>
<body>
    <div id="main">
        <ul id="carousel-navbar">
            <li><a id="navlink-form1">Text</a></li>
            ...
        </ul>
        <div id="formCarousel" class=" carousel slide" >
            <div class="active first item">
                <form id="form1" name="question1">
                    ...
                </form>
            </div>
            ...
        </div>
    </div>
</body>
</html>

澄清不完全相同(实际的是442行),但结构应该是相关的同义词。

2 个答案:

答案 0 :(得分:1)

问题是您要查找的元素未附加到DOM。你必须在调用函数之前添加它:

it("should call slideTo when navbar is clicked", function(){
    var spy = sinon.spy();
    var formView = new Project.Views.FormView({ el : $('#main'), id : 1});
    formView.bind('slideTo', spy);
    $('body').append('<div class="active"><form id="form1" /></div>');


    var event = {};
    event.target = "<div id='form1'></div>";

    formView.sidenavClicked(event);
});

还有一些插件可以更轻松地使用jasmin处理夹具:jasmine-fixturejasmine-dom

答案 1 :(得分:0)

这可能看起来有点天真,但无论如何我都会指出。

在我看来,你实际上并没有在任何地方渲染视图。我这么说是因为你发布的代码都没有在视图上调用.render(),我看不到任何暗示它在幕后发生的事情,这也许可以解释为什么JQuery调用的行为方式与

从Jasmine规范中渲染视图通常很简单:

beforeEach(function () {
  // some element you want to render your view into
  $('#testbed').html(view.render().el);
});

form_id可能未定义,因为您要查找的元素不在DOM中。你真的能从函数中找到那个元素吗?从测试本身开始?

(另外,因为该函数绑定到一个事件,我个人认为通过触发该事件来调用它可能更有意义 - 例如,.click()或div上的任何事件 - 而不是显式调用它。)