2017-05-02 49 views
0

所以基本上我有我想要測試,我們將調用函數A.我想測試,如果函數B被調用函數的內部函數。問題在於函數B在函數A中被解析的Promise異步調用。這將導致sinon斷言失敗,因爲測試將在函數B被調用之前完成!如何測試,如果函數A被調用的測試函數B內,如果它被稱爲異步

這是一個工作代碼場景。

const sinon = require('sinon'); 

describe('functionToBeTested',() => { 
    it('someFunction is called',() => { 
    // spy on the function we need to check if called 
    const spy = sinon.spy(someClass.prototype, 'someFunction'); 
    // call the function being tested 
    functionToBeTested(); 
    // check if spy was called 
    sinon.assert.called(spy); 
    }); 
}); 

class someClass { 
    someFunction() { 
    console.log('Hello'); 
    } 
} 

const somePromise = Promise.resolve(); 

function functionToBeTested() { 
    const instance = new someClass(); 
    // some synchronous code here 
    // if instance.someFunction() is called here the test will pass 
    // . 
    // . 
    // . 
    somePromise.then(() => { 
    instance.someFunction(); 
    // the function is called and Hello is printed but the test will fail 
    }) 
    // . 
    // . 
    // . 
    // some synchronous code here 
    // if instance.someFunction() is called here the test will pass 
} 

回答

1

你的例子有點不合常規。您有functionToBeTested它具有雙重行爲(同時同步和異步)。當您將此方法置於測試中時,應該事先了解並標準化該行爲,以便相應地構建測試和斷言。

在這種情況下的問題是,你試圖驗證功能的行爲是同步模式,雖然內部零件工作在一個隨時忘記時尚 - 即沒有依賴的結果instance.someFunction()方法。

如果functionToBeTested()返回一個承諾 - 因此是異步的設計,這將是你的測試場景的直接。但在這種情況下,您還需要一種非傳統的測試方法。這意味着如果你做類似的事情:

describe('functionToBeTested',() => { 

    it('someFunction is called', (done) => { 

     // spy on the function we need to check if called 
     const spy = sinon.spy(SomeClass.prototype, 'someFunction'); 

     // call the function being tested 
     functionToBeTested(); 

     setTimeout(() => { 
      // check if spy was called 
      sinon.assert.called(spy); 
      done(); 
     }, 10); 

    }); 
});  

測試會通過。這裏發生的是我們通過在回調中使用完成的參數來聲明測試async。此外,我們添加了一個計時器來模擬延遲,然後檢查是否調用了間諜。

由於''忘記''電話只打印出一條信息,等待10ms就足夠了。如果承諾花費較長時間完成,則應等待時間調整。如前所述,非常規實現需要非常規方法。我建議您重新考慮您的要求並重新設計解決方案。

相關問題