2

我正在尝试编写 Jasmine 规范来验证在将模型添加到视图的集合时是否调用了视图的函数。

在视图的初始化函数中我做

this.collection.on('add', this.fooAdded, this);

在我的茉莉花规格中,我正在做:

describe('Foo View', function() {
   it('should call fooAdded when a Foo is added', function() {
      var view = new FooView({collection: new FooCollection()});
      spyOn(view, 'fooAdded').andCallThrough();
      view.delegateEvents();
      view.collection.add({name: 'foo'});
      expect(view.fooAdded).toHaveBeenCalled();
   });
});

我的 fooAdded() 实现将一些内容记录到控制台,所以我知道它正在被调用。然而,间谍没有看到 fooAdded() 已被调用。

见我的jsFiddle

4

2 回答 2

4

您的问题是spyOn用新的包装函数替换了被监视的函数,但您在使用该函数替换它。当您调用spyOn(view, 'fooAdded')附加间谍时,对原始的引用fooAdded已经在集合的侦听器列表中,因此监视该回调为时已晚。

如果您在实例化视图之前fooAdded在视图的原型中窥探:

spyOn(FooView.prototype, 'fooAdded');
var view = new FooView(...);
view.delegateEvents();
//...

那么事情应该会更好。演示: http: //jsfiddle.net/m5Baw/1/(感谢amiuhle更新演示中的 Jasmine 链接)。

顺便说一句,我认为您的视图发生了一些奇怪的事情,您不需要view.delegateEvents()在视图的代码之外,所以您可能想仔细看看。

于 2012-12-27T18:42:31.330 回答
2

我正要回应,“亩太短”正是重点。证明您的间谍未注册的第一件事是使用以下代码而不是您的代码spyOn(view, 'fooAdded').andCallThrough();

spyOn(FooView.prototype, 'fooAdded').andCallFake(function(){
           console.log('fake "fooAdded" called');
        });

这将永远不会被调用,因为fooAdded它已经在集合侦听器中注册。这是更新的jsFiddle

于 2012-12-27T19:09:34.103 回答