2013-12-14 30 views
0

我想測試將錯誤在我的search.coffee類拋出的情況下:Node.js + Mocha + Should.js如何測試eventemitter拋出的錯誤?

讓我們假設我的測試,我FO cn的

search.coffee

{ EventEmitter } = require 'events' 
connectors  = require './connectors' 

class Search extends EventEmitter 
    constructor: (@query, @credentials, dispatch = true) -> 
    @connectors = @_connectors() 

    if @connectors.length == 0 
     # want to test this 
     @emit 'error', new Error 'Search could not be dispatched to any connectors' 

    @_dispatch(query, connector) for connector in @connectors if dispatch 

我有嘗試了以下方法,但是,由於發生錯誤的事件,new Search()本身的返回不會引發錯誤。我怎樣才能捕捉到這個拋出的錯誤?

search_spec.coffee

Search = require '../../src/search' 

describe "search.coffee", -> 

    describe "constructor", -> 
    it 'should return an error if no credentials match loaded connectors', -> 
     new Search("foo", { }, false).should.throw() 

回答

2

呀,沒有什麼是拋出這裏。如果沒有安裝事件偵聽器,則default behavior用於節點打印堆棧跟蹤並退出。它看起來像一個拋出的異常,但你無法捕捉它。諸如should.throwassert.Throw等系統依賴於能夠捕捉到異常。這裏不可能。

現在,有一個問題。您在構造函數中發出了'error'事件。誰有機會撥打on的方法來安裝監聽器,以便當這emit發生時,有人會收到它?該對象尚未構建。該對象本身可以調用on,但外部沒有人可以。

選項:

  1. 不要emit一個錯誤,而是throw錯誤。由於上述原因,如果這是我的代碼,這是我更喜歡的選項。

  2. 向構造函數中添加一個附加參數。這將是一個監聽器,它會立即安裝在自己的監聽器上,以偵聽錯誤事件。所以在測試中,可以將一個監聽器傳遞給構造函數,然後測試它是否被調用。

  3. 如果它沒有任何意義,讓喜歡在第一選項中提到呼叫者安裝監聽器,Search可以安裝自己的監聽器,它可錄製對象是死的(例如,this.dead = true)。然後測試這個標誌。或者如果當前的設計和行爲是所需的(構造函數發出'error',這會導致Node.js退出),請修改上一個選項。設計一種方式來指示Search它正在測試環境中運行。當它檢測到它正在測試時,它會像上一個選項一樣添加一個偵聽器。

+0

有趣的 - 所以在另一個類(Client.coffee),這是不是我原來的問題,綁定到'.on('error')'事件。但據我所知,無論如何,因爲我永遠不會有機會首先實例化一個'Search',然後綁定到'error'事件,我的'Client'類將永遠不會收到這個錯誤事件? – professormeowingtons

+0

沒錯。您必須使用我在答案中列出的選項之一才能解決此問題。我沒有提到的另一個選項,但現在發生在我身上的是將另一個對象用作通信通道。該對象將在「Search」之前創建並傳遞給「Search」的構造函數。一個''Search''對象會在這個通信通道上發出事件。 – Louis

+0

好主意,並感謝您的詳細建議。 – professormeowingtons

相關問題