2012-08-07 16 views
9

Gặp sự cố khi gián đoạn cuộc gọi phương thức trên Bộ định tuyến đường trục để đảm bảo nó gọi đúng phương thức trên một tuyến đường nhất định.Làm gián đoạn cuộc gọi đường Backbone.js bằng Jasmine

đoạn trích từ bài kiểm tra

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

Router

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

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

Tất cả mọi thứ trôi qua, ngoại trừ bài kiểm tra cuối cùng "nên gọi là Chỉ số". Không thành công với thông báo "Chỉ mục gián điệp dự kiến ​​đã được gọi". Ive đã cố gắng biến thể khác

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

tôi cũng có thể thấy "router.index đã được gọi là" đăng nhập đầu ra trong đầu ra kiểm tra từ các chức năng Router.index gốc

Cảm ơn!

EDIT: Một giải pháp

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

Trả lời

15

Nó đã mất quá nhiều thời gian để tôi đến với một số working jsFiddle và câu hỏi đã được trả lời bởi @MarkRushakoff.

Tôi vẫn có một số nhận xét.

Cách Backbone là ràng buộc các tuyến đường thực hiện rất khó khăn để kiểm tra nó.

Điểm có ích là router phương pháp không được gọi trực tiếp vào router dụ, các phương pháp được taked như callbacks và lưu trữ trong một nội Backbone.history.route chờ đợi để thực hiện, check the Backbone.Router.route code.

Thao tác này được thực hiện trong thời điểm hiện tại Router là nhanh chóng, vì vậy bạn phải spy bạn Router.method trước khi bạn khởi tạo các tài liệu tham khảo, vì vậy bạn phải trì hoãn Backbone.history.start cũng sau khi spy đã được kích hoạt.

Khi bạn phải khai báo spy trước khi cá thể bộ định tuyến được tạo, bạn phải thực hiện ở cấp độ Lớp.

Said vì vậy đây là giải pháp đơn giản nhất tôi đến với:

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

Kết luận, tôi nghĩ rằng việc thực hiện Backbone.Router không có một thiết kế trực quan.

+1

Cảm ơn! Có vẻ như đó là cách để đi :) – eldewall

+0

Đây không phải là một cách khả thi để kiểm tra sự kích hoạt của một tuyến đường. Tất cả điều này là thử nghiệm là chức năng chỉ mục đã được ràng buộc với các bộ định tuyến như một cuộc gọi lại, không phải là chức năng thực sự được gọi là khi tuyến đường đã được kích hoạt. Xem [this S.O. post] (http://stackoverflow.com/questions/9215737/testing-routers-in-backbone-js-properly) để biết cách xác minh rằng hàm tuyến đường tương ứng đã được gọi khi một router khớp với một url. – louism2

4

Tôi khá chắc chắn điều này đã làm với cách mà Backbone liên kết với các phương pháp định tuyến của nó khi bạn sử dụng một tuyến đường băm (đặc biệt nếu bạn đang nhìn thấy một giao diện điều khiển đăng nhập chính xác đầu ra). Nghĩa là, router đã liên kết với phương thức gốc index, nhưng gián điệp của bạn đã thay thế phương thức "hiện tại" index.

Bạn có hai lựa chọn:

  • spyOn(@router, "index") trước khi bạn router liên kết với các tuyến đường (có thể khó khăn)
  • Spy trên phương pháp index của mẫu thử nghiệm: spyOn(App.router.prototype, "index"); @router.navigate('', true); expect(App.router.prototype.index).toHaveBeenCalled();
+0

Cảm ơn, điều đó hoạt động :) Tùy chọn số hai là khả thi. Các điệp viên cần phải được thêm vào trước khi một thể hiện mới của router được thực hiện. Tôi đoán thats OK! – eldewall

+0

Tùy chọn một trong những tôi nghĩ là không thể do _routes binding_ được thực hiện trong _initialize_ vì vậy trong thời điểm này bạn có một tham chiếu đến thể hiện ràng buộc đã được thực hiện. – fguillen