2016-12-07 102 views
3

新手寫單元測試和「嘲笑」的概念更爲確切。我有一個基本的功能「addPercentSign」,增加了一個百分號用戶輸入如果是50-100之間:我現在面臨 如何存根有問題的代碼片段[單元測試]

問題

addPercentSign: function (oEvent, control) { 
     var inputVal = oEvent.getParameters().value; 
     var inputNumber = parseFloat(inputVal); 

     if (inputNumber) { 

      if (inputNumber < 50 || inputNumber > 100) { 
       return null; 
      } else { 
       var finalVal = inputNumber.toFixed(1); 
       var finalOutput = finalVal + "%"; 

//Error: cannot setValue of undefined. How can I 'stub' the line below? 
       control.learningCurve.setValue(finalOutput); 

       return finalOutput; 
      }; 
     } 
    } 

的問題

是當我寫這個函數的單元測試,我不能測試返回的值(finalOutput),因爲它上面的行返回一個錯誤,因爲它依賴於DOM元素(control.learningCurve)來設置一個值。由於這是一個單元測試,我必須將這個函數與任何依賴關係隔離。

因此,我需要'模擬''setValue'調用。我想創建一個存根將是有道理的,但我不知道如何?

下面是單元測試代碼,我想測試上述功能(addPercentSign):

function (formatter, viewControls) { 
    "use strict"; 

    var testEvent = { 
     getParameters : function() { 
       return {value : 50} 
     } 
    } 

    QUnit.module("Formatter Functions"); 
    QUnit.test("Add Percent Sign", function (assert) { 

    assert.ok(formatter.addPercentSign(testEvent, viewControls) == '50.0%', "Percent Sign Added: Pass"); 

    }); 
} 

問題

我怎麼能嘲笑的制定者,所以我可以單元測試這個功能沒有DOM依賴關係?:

control.learningCurve.setValue(finalOutput) 

回答

1

可以用作測試雙。

本例使用sinon stub。

sinon.stub(control.learningCurve, 'setValue').returns('value that you need'); 

編輯:

function (formatter, viewControls) { 
"use strict"; 

    sinon.stub(control.learningCurve, 'setValue').returns('value that you need'); 

    var testEvent = { 
     getParameters : function() { 
       return {value : 50} 
     } 
    } 

    QUnit.module("Formatter Functions"); 
    QUnit.test("Add Percent Sign", function (assert) { 

    assert.ok(formatter.addPercentSign(testEvent, viewControls) == '50.0%', "Percent Sign Added: Pass"); 

    }); 
} 
+0

謝謝,你能展示如何插入上面的單元測試?它看起來像第一個參數是control.learningCurve對象,而第二個是我想'存根'的函數? –

+0

是的,它傳遞sinon.stub(對象,「方法」)作爲參數。 Sinon文檔有關於如何使用存根的更多細節。 – SafeHouse

+0

謝謝,但我發現他們的文檔非常難以遵循somone只是學習嘲笑,存根,間諜.. –

0

我不知道,因爲我不是一個JS忍者,但我認爲它不應該是這麼難。

您想要使用的方法位於名爲'learningCurve'的對象內部,該對象位於'control'對象內部。

如果控制是格式化程序裏面,你就不能做到這一點:

formatter.control = {}; 
formatter.control.learningCurve = {}; 
formatter.control.learningCurve.setValue = function() { 
    return something_to_return; 
} 

assert.ok(formatter.addPercentSign(testEvent, viewControls) == '50.0%', "Percent Sign Added: Pass"); 

如果不是內部格式比做到這一點通過創建控件的新實例,並更換裏面有什麼樣的上方。

0

我發現單元測試的主要附加價值之一就是它讓你意識到你的代碼可以被重構的地方。在你的情況下,有2個不同的問題:追加%和修改DOM。通過將這兩個問題重構爲各自的功能,您可以在不嘲笑任何事情的情況下對您的邏輯進行單元測試。

//Formerly addPercentSign 
inputChanged: function (oEvent, control) { 
    var inputVal = oEvent.getParameters().value; 
    var inputNumber = parseFloat(inputVal); 
    var formattedNumber = addPercentSign(inputNumber); 
    control.learningCurve.setValue(formattedNumber); 
} 

function addPercentSign(inputNumber) { 
    if (inputNumber < 50 || inputNumber > 100) { 
     return inputNumber; 
    } 
    var finalVal = inputNumber.toFixed(1); 
    return finalVal + "%"; 
} 

現在您可以輕鬆測試addPercentSign了。你也可以單元測試inputChanged,但這只是單元測試javascript框架。