2012-08-07 9 views
9

Problemy z podglądaniem wywołań metod na routerze szkieletowym w celu sprawdzenia, czy wywołuje właściwą metodę na danej trasie.Szpiegowanie połączeń z Backbone.js za pomocą Jasmine

fragment testu

describe 'Router', -> 
    beforeEach -> 
     @router = new App.Router() 
     Backbone.history.start() 

    afterEach -> 
     Backbone.history.stop() 

    describe 'routes', -> 
     it 'should be defined', -> 
       expect(@router.routes).toBeDefined() 

     describe 'default route', -> 
      it 'should be defined', -> 
        expect(@router.routes['']).toBeDefined() 

      it 'should call index', -> 
       spy = spyOn(@router, "index") 
       @router.navigate('', true) 
       expect(spy).toHaveBeenCalled() 

routera

class App.Router extends Backbone.Router 
    routes: 
     '' : 'index' 

    index: -> 
     console.log "router.index has been called" 

Wszystko przechodzi z wyjątkiem ostatniego testu "powinien zadzwonić indeks". Nie powiedzie się z komunikatem "Oczekiwano, że indeks szpiegowski został wywołany". Ive próbował inne warianty

it "should call index", -> 
    spyOn(@router, "index") 
    @router.navigate('', true) 
    expect(@router.index).toHaveBeenCalled() 

mogę też zobaczyć „router.index została nazwana” wyjście zalogować wyjścia testowego od pierwotnej funkcji Router.index

Dzięki!

EDIT: Jedno rozwiązanie

describe '#1 Solution', -> 
    it 'should call index', -> 
     spyOn(App.Router.prototype, "index") 
     @router = new App.Router() 
     Backbone.history.start() 
     @router.navigate('', true) 
     expect(App.Router.prototype.index).toHaveBeenCalled() 

Odpowiedz

15

To trwało zbyt Dużo czasu dla mnie, aby przyjść z working jsFiddle i pytanie zostało już udzielone przez @MarkRushakoff.

Nadal mam pewne uwagi.

Sposób połączenia kręgosłupa sprawia, że ​​bardzo trudno jest go przetestować.

Chodzi o to, że router metody nie są wywoływane bezpośrednio w przypadku, Router , sposoby są taked jak callbacków i przechowywane w wewnętrznej Backbone.history.route czeka na wykonanie, check the Backbone.Router.route code.

Ta operacja jest wykonywana w tej chwili Router jest instancję, więc trzeba spy swoją Router.method przed instancji odwołanie, tak aby trzeba opóźnić Backbone.history.start również po spy został aktywowany.

Ponieważ musisz zadeklarować spy przed utworzeniem instancji routera, musisz to zrobić na poziomie klasy.

Said więc jest to najprostsze rozwiązanie przyjechałem z:

describe("Router", function() { 
    afterEach(function(){ 
    Backbone.history.stop(); 
    }); 

    it("should call index", function(){ 
    spyOn(App.Router.prototype, "index") 
    var router = new App.Router(); // instance created after spy activation 
    Backbone.history.start();  // it has to start after the Router instance is created 

    router.navigate('', true); 

    expect(App.Router.prototype.index).toHaveBeenCalled(); 
    }); 
}); 

Podsumowując, myślę, że realizacja Backbone.Router nie posiada intuicyjny design.

+1

Dzięki! Wygląda na to, że to jest droga :) – eldewall

+0

To nie jest opłacalny sposób na przetestowanie wyzwalania trasy. Wszystko to jest testowanie, że funkcja indeksu została przypisana do routera jako callback, a nie to, że funkcja jest rzeczywiście wywoływana, gdy trasa została wyzwolona. Patrz [to S.O. post] (http://stackoverflow.com/questions/9215737/testing-routers-inbbackbone-js-properly) w celu sprawdzenia, czy odpowiednia funkcja trasy została wywołana, gdy router dopasuje adres URL. – louism2

4

Jestem całkiem pewien, że to ma związek ze sposobem, że Backbone wiąże się z jego metod routingu podczas korzystania z tras hash (zwłaszcza jeśli widzisz konsolę loguj poprawnie dane wyjściowe). Oznacza to, że router jest związany z oryginalną metodą index, ale twój szpieg zastąpił "bieżącą" metodę.

Masz dwie opcje:

  • spyOn(@router, "index") przed wami router łączy się z drogami (może być trudne)
  • Spy na prototypie za index metody: spyOn(App.router.prototype, "index"); @router.navigate('', true); expect(App.router.prototype.index).toHaveBeenCalled();
+0

Dzięki, że działa :) Opcja numer dwa jest opłacalna. Szpiega musi zostać dodana przed utworzeniem nowej instancji routera. Myślę, że to w porządku! – eldewall

+0

Opcja pierwsza myślę, że nie jest możliwa, ponieważ _routes binding_ jest wykonywane w _initialize_, więc w momencie, gdy masz odniesienie do instancji, wiązanie zostało już wykonane. – fguillen

Powiązane problemy