2012-08-07 15 views
9

Belirli bir rotada doğru yöntemi çağırdığından emin olmak için bir Backbone Router üzerinde casusluk yöntem çağrıları yapmakta zorlanıyor. TestBackbone.js yolunda casusluk yapma, Jasmine ile iletişim kurar

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() 

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

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

Her şey son test "endeksi aramak gerekir" hariç geçer yönlendirici gelen

alıntı. "Beklenen casus indeksi çağrıldı" mesajı ile başarısız. Ive da "router.index adı olmuştur" orijinal Router.index fonksiyonu test çıktısında

Teşekkür çıkışını log görebilen diğer varyantları

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

çalıştı!

DÜZENLEME: bir çözüm

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() 

cevap

15

İki seçeneğiniz vardır working jsFiddle ile gelmek için bana çok zaman ve soru zaten @MarkRushakoff tarafından yanıtladı.

Yine de bazı yorumlarınız var.

Backbone'un yolları bağladığı yol, test etmeyi çok zorlaştırıyor.

noktası yönlendirici yöntem yönlendirici örneği doğrudan adı değildir, yani yöntem geri aramalar olarak almışlardır ve yürütme, check the Backbone.Router.route code bekleyen bir iç Backbone.history.route saklanır. Eğer başvuru örneğini önce Router.methodspy zorunda böylece spy aktive edildikten sonra da Backbone.history.start ertelemek zorunda için çok

Bu operasyon, Router örneğini andan yapılır.

Yönlendirici örneği oluşturulmadan önce spy bildirmeniz gerektiğinden, bunu Sınıf düzeyinde yapmanız gerekir.

Said'in ben bu ile geldi basit çözüm:

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(); 
    }); 
}); 

Sonuç, ben Backbone.Router uygulama sezgisel bir tasarıma değil olduğunu düşünüyorum.

+1

Teşekkürler! Gibi yolu budur :) – eldewall

+0

Bu, bir rotanın tetiklenmesini test etmek için geçerli bir yol değildir. Tüm bu test, indeks fonksiyonunun yönlendiriciye bir geriçağırım olarak bağlı olması, fonksiyonun gerçekte rota tetiklendiğinde çağrılmamasıdır. Bakınız [bu S.O. bir yönlendirici bir url ile eşleştiğinde, ilgili rota işlevinin çağrıldığını doğrulamak için (http://stackoverflow.com/questions/9215737/testing-routers-in-backbone-js-properly). – louism2

4

Bunun bir konsol görüyorsanız özellikle eğer (bir rotalar karma kullandığınızda Omurga yönlendirme yöntemlerine bağlanan bu şekilde ilgisi var eminim doğru çıktı günlüğü. Yani, yönlendirici orijinal index yöntemine bağlanmıştır, ancak casusunuz "geçerli" index yönteminin yerini almıştır. yönlendirici yollarına bağlayan önce prototipin index yöntemine

  • Casus (zor olabilir)

    • spyOn(@router, "index"): Çok aldi spyOn(App.router.prototype, "index"); @router.navigate('', true); expect(App.router.prototype.index).toHaveBeenCalled();
  • +0

    Teşekkürler, bu işe yarar :) Seçenek iki numara uygulanabilir. Router'ın yeni bir örneği oluşturulmadan önce casusun eklenmesi gerekir. Sanırım sorun yok. – eldewall

    +0

    Seçenek 1 _routes binding_ _initialize_ dosyasında yapıldığı için mümkün değil diye düşünüyorum, bu yüzden bağlamanın yapıldığı örneğe başvurduğunuz anda. – fguillen