2013-08-19 51 views
9

有一個在FooView燃煤自定義事件..如何測試後,事件被解僱一個函數被調用?

// views/foo_view.js 

this.trigger("something:happened"); 

相關的FooController結合的處理程序,以照顧的事件......

// controller/foo_controller.js 

initialize: function() { 
    this.fooView = new FooView(); 
    this.fooView.bind("something:happened", this.onSomethingHappened, this); 
} 

onSomethingHappened: function(event) { 
    // Do something else. 
} 

要測試事件處理我會寫爲Jasmine以下測試:

it("should do something else when something happens", function() { 
    var fooController = new FooController(); 
    spyOn(fooController, "onSomethingHappened"); 
    fooController.fooView.trigger("something:happened"); 
    expect(fooController.onSomethingHappened).toHaveBeenCalled(); 
}); 

雖然,測試失敗..

FooView should do something else when something happens. 
Expected spy onSomethingHappened to have been called. 
Error: Expected spy onSomethingHappened to have been called. 
    at new jasmine.ExpectationResult (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:114:32) 
    at null.toHaveBeenCalled (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1235:29) 
    at null.<anonymous> (http://localhost:8888/assets/foo_spec.js?body=true:225:47) 
    at jasmine.Block.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1064:17) 
    at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31) 
    at jasmine.Queue.start (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2049:8) 
    at jasmine.Spec.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2376:14) 
    at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31) 
    at onComplete (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2092:18) 
    at jasmine.Spec.finish (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2350:5) 

測試是否失敗,因爲事件需要的時間超過期望執行時間?

回答

14

的問題是,你在窺視功能函數被綁定到事件之後。當茉莉花創建一個間諜時,它會用另一個函數替代你窺探的功能。

這裏所以會發生什麼,是原來的功能,勢必

this.fooView.bind("something:happened", this.onSomethingHappened, this); 

之後,原來的功能是由間諜取代了事件,但不會對你傳遞給函數任何影響到bind函數。

該解決方案是間諜FooController.prototype.onSomethingHappened您創建一個新的實例之前:

it("should do something else when something happens", function() { 
    var onSomethingHappenedSpy = spyOn(FooController.prototype, "onSomethingHappened"); 
    var fooController = new FooController(); 
    fooController.fooView.trigger("something:happened"); 
    expect(onSomethingHappenedSpy).toHaveBeenCalled(); 
}); 
+0

真棒!我注意到,我實際上**必須在創建間諜後實例化控制器。當我引用'beforeEach'塊中創建的'fooController'時,測試不會**。謝謝! – JJD

+0

完美的作品。謝謝! – RY35