2017-08-22 22 views
-3

我的代碼:爲什麼期待的setTimeout語句不運行

before(function _before(){ 
    this.spyLog = sinon.spy(this.myOBJ.log, 'warn'); 
    }); 

    after(function _after(){ 
    this.spyLog.restore(); 
    }); 

    it('should', sinon.test(function() { 
    const stubFindOne = this.stub(this.myOBJ, 'findOne'); 
    stubFindOne.returns(bluebird.reject(new Error('Should have failed'))); 
    this.myOBJ.toBeTestedFunction({}); 
    setTimeout(function _expect() { 
     console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++'); 
     console.log('this.spyLog', this.spyLog.args); 
     expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed'); 
     console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++'); 
    }, 100); 
    })); 

爲什麼_expect功能無法運行?謝謝

UPDATE 試過以下代碼,但得到了Error: timeout of 2000ms exceeded。我認爲這是因爲done不叫。我需要this.myOBJ.toBeTestedFunction({});完成運行,然後運行預期。如何修復代碼?

it('should', sinon.test(function(done) { 
    const stubFindOne = this.stub(this.myOBJ, 'findOne'); 
    stubFindOne.returns(bluebird.reject(new Error('Should have failed'))); 
    this.myOBJ.toBeTestedFunction({}); 
    setTimeout(function _expect() { 
     console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++'); 
     console.log('this.spyLog', this.spyLog.args); 
     expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed'); 
     console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++'); 
      done(); 
    }, 100); 
    })); 

UPDATE

我以下代碼工作。但如何改善呢?

it('should', sinon.test(function() { 
    const stubFindOne = this.stub(this.myOBJ, 'findOne'); 
    stubFindOne.returns(bluebird.reject(new Error('Should have failed'))); 
    return new bluebird.Promise((resolve, reject) => { 
     this.myOBJ.tobetestedFunction(); 
     resolve(); 
    }) 
    .delay(1000) 
    .then(() => { 
     expect(this.spyLog.args[2][0].toString()).to.be.equal('Error: Should have failed'); 
    }); 
    })); 

回答

1

作爲寫入,測試案例結束之前的任何異步代碼(諸如回調setTimeout)可以運行。在it呼叫中添加done參數,並在setTimeout回叫結束時呼叫done()

這就是說,我想我會回去把我說的代碼樣本放在一起,這讓我看起來更接近你的代碼......這看起來最終會給你帶來麻煩。看起來你正在期待一些異步事件能夠讓你的期望保持一致,而不是控制執行這些事件,而只是說「呃,它們應該在100個刻度內完成......」這不是一個好的計劃。

THAT說,它看起來像

it('should', sinon.test(function(done) { 
    const stubFindOne = this.stub(this.myOBJ, 'findOne'); 
    stubFindOne.returns(bluebird.reject(new Error('Should have failed'))); 
    this.myOBJ.toBeTestedFunction({}); 
    setTimeout(function _expect() { 
     console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++'); 
     console.log('this.spyLog', this.spyLog.args); 
     expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed'); 
     console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++'); 
     done(); 
    }, 100); 
    })); 

UPDATE - 你提到加入done沒有工作(超時錯誤);這幾乎可以肯定是因爲你在你的函數中使用的sinon.test包裝器正在迎頭趕上。我不熟悉sinon(並且快速谷歌沒有提供test方法的文檔),但總的來說,您需要的是sinone.test返回的函數(1)採用done參數,以及(2)把它作爲回調的第一個參數傳遞給它。在你的函數中放入一個done參數顯然不會發生。您必須查閱sinon文檔。 (你試圖使用的茉莉花功能是「異步測試」,但是因爲sinon試圖成爲框架無關的,我不確定他們是否/他們如何解決這個問題。也許只是關於測試方法,需要額外的參數?)

關於爲什麼這不是一個好的測試方法的後續問題:對未在實時計算環境中編碼的事件施加實時約束從來就不是一個好主意。如果要滿足條件需要250個滴答聲,那真的是測試失敗嗎?如果是這樣,你正在測試性能 - 而不是功能 - 即使如此,你在這裏有一個測試,可以傳遞一些硬件,並在其他硬件上失敗,或者測試「一段時間」......不是真正的行爲想從一個自動測試套件。

再加上那些你正在等待的異步事件幾乎可以肯定是你的測試依賴的行爲之外的代碼 - 在這種情況下,它不是一個適當的單元測試。

做這種測試的「正道」,是明顯更加困難,因爲你會嘲笑的外部依賴和使用嘲笑對預先測試朝着預期

+0

試圖評估,但得到了'錯誤:超時超過2000毫秒' – BAE

+0

您能否介紹一下關於「這不是一個好計劃」的更多細節? – BAE

+0

是的。我同意。但是這是我爲現有代碼編寫測試的工作,現在我不應該改變它。如何爲異步函數編寫適當的單元測試? – BAE