問題描述
在監視骨干路由器上的方法調用以確保它在給定路由上調用正確的方法時遇到問題.
Having problems spying method calls on a Backbone Router to ensure it calles the right method on a given route.
測試摘錄
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"
除了最后一個測試應該調用索引"之外,一切都通過了.它失敗并顯示消息預期的間諜索引已被調用".我試過其他變種
Everything passes except the last test "should call index". It fails with the message "Expected spy index to have been called". Ive tried other variants
it "should call index", ->
spyOn(@router, "index")
@router.navigate('', true)
expect(@router.index).toHaveBeenCalled()
我還可以在原始Router.index函數的測試輸出中看到router.index has been called"日志輸出
I can also see the "router.index has been called" log output in the test output from the original Router.index function
謝謝!
一種解決方案
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()
推薦答案
我花了太多時間來提供 working jsFiddle 并且@MarkRushakoff 已經回答了這個問題.
It has took too much time to me to come with a working jsFiddle and the question has been already answered by @MarkRushakoff.
我還有一些意見.
Backbone 綁定路由的方式使得測試變得非常困難.
The way Backbone is binding the routes make very difficult to test it.
重點是路由器methods并不是直接在路由器instance中調用的,方法是作為callbacks存放在一個內部 Backbone.history.route
等待執行,檢查 Backbone.Router.route 代碼.
The point is that the router methods are not called directly in the router instance, the methods are taked as callbacks and stored in an internal Backbone.history.route
waiting for execution, check the Backbone.Router.route code.
這個操作是在 Router
被實例化的那一刻完成的,所以你必須在實例化引用之前 spy
你的 Router.method,所以你必須在 spy
被激活之后延遲 Backbone.history.start
.
This operation is done in the moment the Router
is instantiate, so you have to spy
your Router.method before you instantiate the reference, so for you have to delay Backbone.history.start
also after the spy
has been activated.
由于您必須在創建路由器實例之前聲明 spy
,因此您必須在 Class 級別進行.
As you have to declare the spy
before the router instance is created you have to do it in a Class level.
這么說,這是我提供的最簡單的解決方案:
Said so this is the simplest solution I came with:
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();
});
});
結論,我認為Backbone.Router
的實現沒有直觀的設計.
Conclusion, I think the Backbone.Router
implementation has not an intuitive design.
這篇關于使用 Jasmine 監視 Backbone.js 路由調用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!