Node.js:遇到摩卡问题,并期望to.throwError

我正在尝试为Node创build一个简单的login模块。 我试图用TDD的方式来做,但我还是很陌生,所以任何能够帮助我更好地理解的技巧或资源都会很棒。

我的问题来了,当我查询数据库与无效的数据,我期待着一个错误。 如果我手动testing应用程序 – 这是很好的错误。 但是,当我尝试用Mocha和Expect.js来testing它时,我得到Error: expected fn to throw an exception 。 如果我将代码从to.throwError()切换到to.not.throwError()那么错误就会被正确引发。 我认为这个问题是在我尝试asynchronoustesting和error handling的地方。 第一个testing通过罚款。

谢谢参观。

基于SebastianG指令的新代码

login.js

 var MongoClient = require('mongodb').MongoClient; exports.login = function(callback, email, password) { MongoClient.connect("mongodb://localhost:27017/stockalertDev", function(err, db) { if (err) { return err; } var collection = db.collection('users'); if (email) { collection.findOne({email:email}, function(err, item) { try { if (err) { console.log('error'); throw new Error('error finding email'); } else { if (item) { if (item.password == password) { console.log('logged in'); //callback(null, item); //return item; } else { console.log('here'); throw new Error('Email and password not matching'); } } else { throw new Error('Email not found'); } } } catch (err) { console.log('catch error here'); callback(err, null); } finally { console.log('finally here'); callback(null, item); } }); } }); } 

testing/login-test.js

 var expect = require('expect.js'), assert = require('assert'), mocha = require('mocha'), mongo = require('mongodb'); var login = require('../login'); describe('login', function() { it('should login a real user', function(done) { expect(function() { login.login(function(err, item) { //console.log(item); if (err) throw err; done(); }, 'email', 'password') }).to.not.throwError(); }); it('should error on unfound email', function(done) { expect(function() { login.login(function(err, item) { console.log(err); if (err) throw err; done(); }, 'ert','wqew') }).to.throwError(); }); it('should error on incorrect match', function(done) { expect(function() { login.login(function(err, item) { console.log(err); throw err; done(); }, 'email','wqew') }).to.throwError(); }); }); 

旧代码

login.js

 var MongoClient = require('mongodb').MongoClient; exports.login = function(email, password, callback, errCallback) { MongoClient.connect("mongodb://localhost:27017/stockalertDev", function(err, db) { if (err) { return err; } var collection = db.collection('users'); if (email) { collection.findOne({email:email}, function(err, item) { try { if (err) { console.log('error'); throw new Error('error finding email'); errCallback(err); } else { if (item) { if (item.password == password) { console.log('logged in'); callback(item); //return item; } else { console.log('here'); throw new Error('Email and password not matching'); } } else { throw new Error('Email not found'); } } } catch (err) { errCallback(err); } }); } }); } 

testing/login-test.js

 var expect = require('expect.js'), assert = require('assert'), mocha = require('mocha'), mongo = require('mongodb'); var login = require('../login'); describe('login', function() { it('should login a real user', function(done) { assert.doesNotThrow(function() { login.login('email','password',function() { done(); }, function(err) { if (err) throw err; done(); }); }); }); it('should error on unfound email', function(done) { expect( function() { login.login('atreq','a', function() { console.log('true'); }, function(err) { console.log(err); throw err; })}).to.throwError(); }); it('should error on incorrect match', function(done) { expect(function() { login.login('email','apassword', function() { console.log('true'); done(); }, function(err) { console.log(err); throw err; }) }).to.throwError(); }); }); 

在asynchronous节点代码中使用exeptions是一个坏主意(至less目前来说)。 有一个叫做域名的概念可以帮助你,但是却是非常实验性的。

我build议这样做的节点方式:保留您的callback的第一个参数的错误。 小例子:

 function getUserData(cb) { var userData = // ... if (userData === null) { cb(new Error('Something bad happend.')); } else { cb(null, userData) } } 

如果您想使用errorCallback,请使用它:

 errCallback(new Error('Email not found')); 

比你可以做这样的事情(大多数testing框架为此提供了辅助方法,但是我不是那种熟悉Mocha和它的模块):

 it('should login a real user', function(done) { login.login(function(err, item) { expect(err).to.be(null); expect(item).not.to.be(null); done(); }, 'email', 'password'); }); it('should error on unfound email', function(done) { login.login(function(err, item) { expect(err).not.to.be(null); expect(item).to.be(null); done(); }, 'ert','wqew'); });