2016-03-15 83 views
0

在使用Sinon.js和Buster.js進行測試時,我無法使用模擬來替換我的類的依賴關係。與Sinon.js混淆模擬方法

我正在測試B類,它依賴於A類。我使用Sinon.js創建A類的模擬對象,並將它傳遞到B類的一個實例中。在我的測試中,我將doSomething然後調用對象A的getData方法。(儘管getData方法實際上在A的原型上,而不是A本身)。

但是當我運行測試我得到的錯誤:

TypeError: a.getData is not a function 

如果我嘗試和存根的原型的getData方法,然後我得到的錯誤:

TypeError: Attempted to wrap getData which is already stubbed 

出現的錯誤在我設置的線路上mock_A.expects('getData')。 這是類和測試我跑:

function A(){}; 
A.prototype = { 
    "getData" : function(oDataToGet, cb) { 
     var aData = ['someData']; 
     cb(aData); 
    } 
} 
function B() { 
    var a; 
    this.setA = function(oA){ 
     a = oA; 
    }; 
    this.doSomething = function(oObj){ 
     a.getData({}, function(aData){if(!aData){throw new Error('No data');} oObj.data = aData[0];}); 
    } 
} 


var oB, assert = buster.referee.assert; 
buster.testCase('myTest', { 
    "setUp" : function() 
    { 
     oB = new B(); 
    }, 
    "test_Mock" : function() 
    { 
     var mock_A = sinon.mock(new A()); 
      oB.setA(mock_A); 
    //  sinon.stub(A.prototype, 'getData').callsArgWith(1, ['hi']); 
     mock_A.expects('getData') 
      .withArgs({}) 
      .once(); 
     var oTestObj = {}; 
     oB.doSomething(oTestObj) 
     mock_A.verify(); 
    } 
}); 

編輯2016年3月16日補充: 一種解決方法是使用一個存根實例,而不是一個模擬,然後設置你需要的方法檢查以一種期待:

var stubbed_A = sinon.createStubInstance(A); 
stubbed_A.getData = sinon.expectation.create('getData') 
    .withArgs({}) 
    .once(); 
oB.setA(stubbed_A); 
var oTestObj = {}; 
oB.doSomething(oTestObj); 
stubbed_A.getData.verify(); 

回答

0

有sinonJS等嘲笑框架(像的Mockito,JMock的等)之間的差,創建這種誤解。在大多數的嘲諷框架,創建嘲笑的依賴,並在目標將要測試(SUT)注入它,像你一樣:

var mock_A = sinon.mock(new A()); 
oB.setA(mock_A); 

然而,在sinonJS,你必須注入原始對象和使用生成的模擬對象來分配期望值。所以,如果你改變以前的2線,或與以下,您的測試按預期工作:

var a = new A(); 
var mock_A = sinon.mock(a); 
oB.setA(a); 

存根是比較合適的,如果我們想控制我們正在測試的對象的依賴關係的行爲。當我們想確保一個特定的事件會發生在我們正在測試的對象(通過期望)的依賴性上時,Mock更合適。所以,在這種情況下,一個模擬對象比一個存根更適合,就像你第一次嘗試一樣。