SpyOn使用茉莉花的骨干视图方法

mis*_*hod 18 view spy backbone.js jasmine

我有一个骨干视图,我想创建一个测试来确认某个元素上的click事件将调用绑定到该元素的函数.我的观点是:

PromptView = Backbone.View.extend({
        id:"promptPage",
        attributes:{
            "data-role":"page",
            "data-theme":"a"
        },
        events:{
            "click #btnYes":    "answerYes",
            "tap #btnYes":      "answerYes"
        },
        render: function(){
            $(this.el).html(_.template($('#promptPage-template').html(), this.model.toJSON()));

            return this;
        },
        answerYes: function(){
            alert('yes');
        }
    });
Run Code Online (Sandbox Code Playgroud)

我的规格是:

beforeEach(function() {
            model = new PromptModel;
            view = new PromptView({model:model});
            loadFixtures('promptPage.tmpl');
        });

 it("should be able to answer a question with yes", function() {
                var button = $("#btnYes", view.render().el);
                expect(button.length).toBe(1);

                spyOn(view, 'answerYes');

                button.click();
                expect(view.answerYes).toHaveBeenCalled();

            });
Run Code Online (Sandbox Code Playgroud)

但是上面的视图定义在原型proto上创建了answerYes方法,但是间谍在视图中的实际实例上创建了一个函数,所以我最终得到了一个view.answerYes(),这是间谍和视图.__ proto __.answerYes,这是我真正想要窥探的那个.

如何创建一个间谍,以便它覆盖视图定义的answerYes方法?

Fer*_* Gm 54

嗨,我今天有同样的问题.我刚刚找到解决方案,在创建spyed方法(answerYes)后,你必须刷新视图的事件来调用新的spyed方法;):

[...]

    spyOn(view, 'answerYes');
    view.delegateEvents();

    button.click();
    expect(view.answerYes).toHaveBeenCalled();

[...]

有关委托事件的更多信息

玩得开心!


Der*_*ley 1

TL;DR:监视实例方法,而不是原型。

我认为你需要以不同的方式设置你的测试。块中有太多的担忧和太多的期望it,而且你还污染了全局命名空间,这可能会导致测试出现问题。

beforeEach(function() {
  loadFixtures('promptPage.tmpl');

  var model = new PromptModel();
  this.view = new PromptView({model:model});
  this.view.render();

  this.button = this.view.$("#btnYes");
});

it("should render the button", function(){
  expect(this.button.length).toBe(1);
});

it("should be able to answer a question with yes", function() {
  spyOn(this.view, 'answerYes');

  this.button.click();
  expect(this.view.answerYes).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

您并不严格需要对按钮长度的期望。如果按钮没有长度(未找到),您将遇到其他失败。但您可能希望它存在,以便更容易地找出视图未正确渲染的情况。

你也应该view像你一直在做的那样监视该实例。的定义PromptView添加了一个answerYes方法,是的,但是您想要监视的是视图实例,而不是原型。

如果您监视原型的方法,那么每次您尝试在测试中使用此视图时,该answerYes方法都将是监视方法,而不是实际方法。这听起来不错,但会导致问题,因为多次调用此方法时您将无法访问有效的间谍数据。它只会累积对该一名间谍的所有呼叫。如果您尝试两次监视原型方法,您最终可能会得到一个间谍的间谍,这将是一件奇怪的事情,并且可能会导致问题。