2015-11-19 63 views
0

我正在使用Mocha作爲我的node.js應用程序的測試框架。使用摩卡單元測試異步 - 瀑布

我有一個使用async-waterfall節點模塊的現有模塊。我正在爲它編寫一個單元測試用例。我無法爲數組中的第二個函數編寫測試用例。我如何將通過一個函數的結果到下一個功能的陣列 var async = require('async');

module.exports.resetPassword = function(req,res,next){ 
async.waterfall([ 
    function(done){ 
    var token = do something; 
    done(err,token); 
    }, 
    function(token,done){ 
     //do some stuff 
    res.status(200).send('success'); 
    }, 
    ]function(err){ 
    //send failure response 
    }); 
}; 
+0

嗨,我不太瞭解這個問題。你是否試圖測試第二個瀑布方法而不管第一個瀑布方法?你能改變方法嗎?還是它給了? –

+0

嗨,在第一個功能我能夠得到一些價值的令牌。我需要將此令牌傳遞給第二個函數。我無法更改該方法,因爲它是現有方法 –

+0

我面臨的問題是控件轉到異步瀑布中的第一個函數,但調用完成後(err,token)被調用,控件不會進入第二個函數(令牌,完成) –

回答

1

我想我現在明白了問題。 在您的測試 - 你執行這行:

user.resetPassword(request,response,next); 

並且之後 - 行:

cryptoStub.restore(); 

的問題是 - 這async.waterfall將啓動第一種方法,但它運行前第二個,它將運行單元測試的下一行,因此你不會看到下一個方法。將解決它的代碼將如下所示:

user.resetPassword(request,response,function(err) { 
    cryptoStub.restore(); 
    done(); 
}); 

它看起來更好嗎?

+0

嗨吉拉德,感謝您的答案。你的解決方案工作:)。由於我是node.js的新手,所以我花了一些時間來理解。它實際上對我沒有寫入crytoStub,resetPassword內的restore()。我沒有注意到,調用done()之後,調用最終進入第二個函數。來自.NET MS Test後臺,我期望在執行user.resetPassword()時執行第二個函數的調用,而不是在控制進入crypto.restore()後執行。需要更多地關注異步單元測試。謝謝您的幫助 –

0

我的代碼如下所示的任何提示。我的問題是圍繞這個方法編寫一個單元測試用例。我正在用摩卡和sin for一起用來存根。我寫單元測試是

單元測試

it("Should return an error if there is an error in retrieving the user details from the db",function(done) 
{ 
    request={ 
     body:{ 
      email:'[email protected]' 

     } 
    }; 

    var expectedMessageFromCrypto = '12121212121'; 
    var cryptoStub = sinon.stub(crypto, "randomBytes",function(err,callback){ 
     callback(null,expectedMessageFromCrypto); 
    }); 

    user.resetPassword(request,response,next); 

    cryptoStub.restore(); 
    done(); 
}); 
}); 

的resetPassword模塊

methods.exports.resetPassword = function (req, res, next) { 
var token = null; 
async.waterfall([ 
    function (done) { 
     crypto.randomBytes(16, function (err, buf) { 
     if(err){ 
      return res.status(400); 
     } 
     else{ 
      token = buf.toString('hex'); 
     } 
     done(err, token); 
     }); 
    }, 
    function (token, done) {    
    var user = getUserInformation(req.body.email); 
     sendEmail(user, done); 
    } 
], function (err) { 
    if (err) { 
     logger.error('error in sending confirmation mail'); 
     return next(err); 
    }   
    res.status(200).send('success'); 
}); 
}; 
+0

您的代碼實際上看起來應該可以工作。我也在PC上試了一下,稍做了些改動,然後到了第二種方法。也許它卡在getUserInformation?你可以在不同的位置添加console.log,以便你確切地知道它卡在哪裏? –

+0

我添加了一個console.log並獲得了預期的值。對我而言,當我從我的單元測試代碼進行調試時,控件沒有輸入getUserInformation。在涉及加密函數之後,它剛剛從整個模塊中出來。我在單元測試中錯過了什麼嗎?當我調試我的prod代碼時,它運行良好。不知道如果我在我的單元測試案例中丟失任何東西 –

+0

我發佈了另一個答案 –