2013-08-19 15 views
9

C'è evento personalizzato sparato in FooView ..Come verificare che una funzione sia stata chiamata dopo che è stato attivato un evento?

// views/foo_view.js 

this.trigger("something:happened"); 

La associato FooController lega un gestore di prendersi cura della manifestazione ...

// controller/foo_controller.js 

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

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

Per testare la gestione degli eventi vorrei scrivere il seguente test per 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(); 
}); 

Anche se, il test fallisce ..

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) 

Il test ha esito negativo perché l'evento richiede più tempo dell'aspettativa per l'esclusione?

risposta

14

Il problema è che si spiare una funzione dopo che la funzione è stata associata all'evento. Quando il gelsomino crea una spia, sostituirà la funzione che spii con un'altra funzione.

Che cosa succede qui, è che la funzione originale è legata alla manifestazione

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

Dopo di che, la funzione originale è sostituito dal spia, ma ciò non avrà alcun effetto sulla funzione che si passa alla funzione bind.

La soluzione per questo è di spiare FooController.prototype.onSomethingHappened prima di creare una nuova istanza:

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

Impressionante! Ho notato che in realtà ** devo istanziare ** il controller dopo aver creato la spia. Il test ** non ** funziona quando mi riferisco a un 'fooController' creato in un blocco' beforeEach'. Grazie! – JJD

+0

Funziona perfettamente. Grazie! – RY35

Problemi correlati