2011-11-29 80 views
3

我正在編寫一些JavaScript類(backbone.js視圖,用Coffeescript編寫)的規範,我想確保一個視圖構造另一個視圖。使用Jasmine監聽Javascript構造函數

我試圖通過刺探構造函數來做到這一點,像這樣:

describe 'Avia.AviaView', -> 

    beforeEach -> 
    @aviaView = new Avia.AviaView() 
    @matricesView = new Backbone.View() 
    spyOn(Avia.MatricesView, 'constructor').andReturn @matricesView 

    describe 'initialize', -> 

    beforeEach -> 
     @aviaView.initialize() 

    it 'creates a new MatricesView ', -> 
     expect(Avia.MatricesView.constructor).toHaveBeenCalledOnce() 

initialize()通話AviaView肯定會導致MatricesView構造函數被調用,禮貌這一行:

new Avia.MatricesView($("#tabs-3")).initialize() 

它絕對有效;如果我手動運行應用程序,我可以看到在initialize()期間被調用的構造函數。但是我的茉莉花規格失敗:

Running Jasmine specs... 
F 

Avia.AviaView initialize creates a new MatricesView . (/Users/dev/avia/spec/javascripts/views/avia_view_spec.js.coffee:13) 
    Expected constructor to be called exactly once, but was called '0' times (line ~14) 
    expect(Avia.MatricesView.constructor).toHaveBeenCalledOnce(); 

FAIL: 1 test, 1 failure, 0.008 secs. 

跟我談過的幾個同事,他們一致認爲這應該工作 ...誰能建議刺探構造的一個好辦法嗎?

+0

從乍一看,這似乎是它與範圍有關。第二個beforeEach函數如何訪問[at] aviaView的第一個實例?嘗試改變beforeEach - > beforeEach =>,這樣它會保持父範圍。也可以嘗試在aviaView之前定義[at] aviaView視圖。 CoffeeScript不像Ruby那樣[at]自動使它成爲一個實例變量。所以不讓我輸入符號。 – Sandro

+0

謝謝 - 我試圖將所有內容都移動到同一個範圍內,但問題仍然存在。我很確定問題在於我在做構造函數的時候「做錯了」......但是我不知道什麼是正確的方式_is_。 –

回答

5

如何:

describe 'Avia.AviaView', -> 

    beforeEach -> 
    @aviaView = new Avia.AviaView() 
    @matricesView = new Backbone.View() 
    spyOn(Avia, 'MatricesView').andReturn @matricesView 

    describe 'initialize', -> 

    beforeEach -> 
     @aviaView.initialize() 

    it 'creates a new MatricesView ', -> 
     expect(Avia.MatricesView).toHaveBeenCalledOnce() 
+0

如果我在監視一個內置對象(如Date),該怎麼辦? 'spyOn(日期, '構造')andCallThrough(); var d = new Date(); expect(Date.constructor).toHaveBeenCalled();' – jab

+0

如果JS運行時不允許你修改核心對象/類,你需要創建一個包裝對象並在你正在測試的類中使用它。這是靜態語言中的一種常見技術(其中模擬/存根較難)。 –