2017-04-12 68 views
0

我對Ember有點新,並試圖測試尋呼機組件。簡化的組件看起來是這樣的:Ember組件測試 - 如何在未調用外部動作時單元測試組件的動作?

export default Ember.Component.extend({ 
    index: 0, 
    actions: { 
     next() { 
      this.incrementProperty('index'); 
     } 
    } 
}); 

我想測試下一個()動作確實增加索引屬性預期。我寫了這樣一個單元測試:

test('next should increment the index by 1', function (assert) { 
    const component = this.subject(); 

    assert.equal(component.get('index'), 0, 'Index should be 0'); 

    component.get('actions').next(); 
    assert.equal(component.get('index'), 1, 'index should be 1'); 
}); 

但它失敗,錯誤「this.incrementProperty不是函數」。調試時,當在next()函數中時,測試中的「this」不是組件的上下文 - 它是next()作爲其唯一屬性的對象。

我不知道這是否是因爲我是如何調用在測試中nextPlace行動。我知道我可以寫一個集成測試的點擊次數將觸發這一行動,並比較了UI,以確保它改變了按鈕,但似乎很令人費解,當所有我想要測試的是函數本身與預期相符。如果它是一個傳遞給此組件的動作(閉包動作),我知道我可以在集成測試中設置一個虛擬函數,將其傳遞給組件,並查看它是如何響應的。但是這個動作並沒有把一個動作傳遞給它。

我意識到我的測試是非常基本的功能,而這部分是要了解如何測試在組件上的動作不調用外部(到組件)的行動。

回答

2

如果你不表達你對不寫一個集成測試的動機,我只能建議你寫一個集成測試。海事組織,你的理由是有效的。我有3個建議爲您的案例啓動單元測試。

首先:不工作的原因是「component.get('actions').next獲取到next函數的引用,沒有任何上下文,以便this是不是在調用中的有效爲了使它有效,只要綁定組件,如下所示。 :

component.get('actions').next.bind(component)(); 

而是因爲它是提取它的上下文next我不喜歡這一點,並再次將其綁定我們這樣做是bind的事情,因爲我們知道,next函數在給this參考它。代碼

所以我的第二個建議是「觸發事件的一些方法」。爲了觸發它,看看下面的代碼:

component.send('next'); 

IMO,這是更好。我們不需要知道「下一步在做什麼」。我們只是觸發一個事件。

但是,這是處理燼組件的生命週期。我們接受這種情況:有一個稱爲actions的特定散列,我們可以通過send來觸發它。 (這是完全沒問題。)而不是處理actions的,我們可以從action handling單獨doing something。因此,您可以定義另一個函數來執行您所需的操作,並只需從您的操作處理程序調用它即可。 (好吧,在這種情況下,我們又需要知道什麼功能是通過動作處理程序調用但這似乎更清楚我。)如下圖所示:

next(){ 
    this.incrementProperty('index'); 
}, 
actions:{ 
    next(){ 
    this.next(); 
    } 
} 

您可以在this twiddle看到所有三個備選方案。