javascript - Node.js:遇到 mocha 问题并期望 to.throwError

标签 javascript node.js tdd mocha.js

我正在尝试为 Node.js 构建一个简单的登录模块。我正在尝试以 TDD 方式进行操作,但我对它还是陌生的,所以任何有助于我更好地理解它的提示或资源都会很棒。

当我查询包含无效数据的数据库时,我的问题就来了,我预计会出现错误。如果我手动测试应用程序,则会抛出错误 - 这很好。但是,当我尝试使用 Mocha 和 Expect.js 对其进行测试时,我得到了 Error: expected fn to throw an exception。如果我将代码从 to.throwError() 切换到 to.not.throwError(),错误就会被正确抛出。我认为问题出在我尝试异步测试和错误处理的某个地方。第一个测试顺利通过。

感谢您的关注。

基于 SebastianG 说明的新代码

登录.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);
            }

            });
        }

    });
}

test/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();
    });
});

旧代码

登录.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);
            }
            });
        }

    });
}

test/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();
    });
});

最佳答案

在异步 Node 代码中使用异常不是一个好主意(至少目前是这样)。有一个概念叫Domains这可能对您有所帮助,但目前还处于实验阶段。

我建议采用 Node 方式:为错误保留回调的第一个参数。小例子:

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'));

你可以做这样的事情(大多数测试框架为此提供辅助方法,但我不太熟悉 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');
});

关于javascript - Node.js:遇到 mocha 问题并期望 to.throwError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15986813/

相关文章:

javascript - 如何创建一个以变量为名称的对象?

javascript - 如何对嵌套对象进行字符串化以使用 queryParams 发出 graphql/GET 请求?

javascript - 在 discord.js 中的时间限制之前获取收集的消息

unit-testing - 测试后端 api 端点是否被视为单元测试?

如果日期在范围内,则 JavaScript 删除类

javascript - 如何在我的代码中使用 jquery 验证和 jquery 自动完成

javascript - 如何在 javascript 中连接多行字符串?

javascript - 脚本中的阻塞 Node

unit-testing - 单元测试理念

unit-testing - 将TDD用于库/API代码和将BDD用作集成测试有意义吗?