摩卡路线testing不是asynchronous执行的
我已经开始与摩卡工作,我有一个特定的testing案例的问题。 这里是代码:
var assert = require("chai").assert; var request = require('supertest'); var http = require("http"); var conf = require("../config/config"); var app = require("../app"); var mongoose = require('mongoose'); var User = mongoose.model('User'); describe('User controller', function(){ describe('POST /register', function(){ it('should return false when the parameters are not unique', function (done) { request(app) .post('/user/register') .send({username:"janette_doe", email:"janette_doe@gmail.com", password:"test123"}) .expect('Content-Type',/json/) .expect({success:true, redirect:'/user/registerConfirmation'}) .end(function(err, res) { if (err) { return done(err); } request(app) .post('/user/register') .send({username:"janette_doe", email:"janette_doe@gmail.com", password:"test123"}) .expect('Content-Type',/json/) .expect({success:false}, done); }); }); });
我期待的结果是错误的,因为在数据库中插入用户后,唯一的索引规则应该引发一个错误。 当我运行这个testing时,我得到这个: {success: true, redirect: '/user/registerConfirmation'}
,我应该得到这个: {success: false}
。 我注意到,当我没有清除每个testing之前的数据库(在utils.js)我得到了预期的价值。 由于asynchronous错误,我得到这个错误吗? 我怎样才能重写这个testing,以确保它的工作?
谢谢
档
util.js包含testing序列的configuration:
'use strict'; process.env.NODE_ENV = 'test'; var config = require('../config/config'); var mongoose = require('mongoose'); beforeEach(function (done) { mongoose.connection.db.dropDatabase(); return done(); }); afterEach(function (done) { return done(); });
user.js用户模型:
var mongoose = require('mongoose'), Schema = mongoose.Schema, var UserSchema = new Schema({ username: {type: String, required: true, unique: true}, email: {type: String, required: true, unique: true}, password: {type: String, required: true}, status: {type: Number, default:0} }); UserSchema.virtual('date') .get(function(){ return this._id.getTimestamp(); }); UserSchema.pre('save', function(next) { //Password encryption ... }); mongoose.model('User', UserSchema);
user.js(控制器)是所有用户路由的控制器。
... router.post('/register', function (req,res,next){ var newUser = new User({ username: req.body.username , email: req.body.email , password: req.body.password }); newUser.save(function(err){ if(err){ res.send({success: false}); }else{ var newToken = new UserToken({ userId: newUser._id , email: newUser.email }); newToken.save(function(err){ if(err){ res.send({success: false}); }else{ res.send({success: true, redirect: '/user/registerConfirmation'}); } }); } }); }); ...
编辑
我已经尝试了end()函数,它仍然无法正常工作。
如何在testingtesting套件中连接超类请求存在问题 – 第二个请求未被正确调用。 当你没有清理数据库时,testing在第一个.expect({success: true, ...})
上失败了,你正在得到预期的值。
正确的方法是使用.end
方法执行第一个请求,检查潜在错误,然后执行第二个请求以查看是否失败:
describe('User controller', function(){ describe('POST /register', function(){ it('should return false when the parameters are not unique', function (done) { request(app) .post('/user/register') .send({username:"janette_doe", email:"janette_doe@gmail.com", password:"test123"}) .expect('Content-Type',/json/) .expect({success:true, redirect:'/user/registerConfirmation'}) .end(function(err, res) { // Check if first request has failed (it should not!) if (err) { return done(err); } // Testing the second, not unique request. that should fail request(app) .post('/user/register') .send({username:"janette_doe", email:"janette_doe@gmail.com", password:"test123"}) .expect('Content-Type',/json/) .expect({success:false}, done); }); }); });
在mocha中,当asynchronous调用完成时,应该调用done()函数,而不pipe错误是否被触发。 另外,使用.done()函数(它是promise API的一部分)来结束promise链,并确保捕获到任何exception。 如果没有完成function,您可以完全忽略运行时错误,因为它们被promise库禁止。