如何在mongoose中使用mocha
Mocha: Mocha是一个用于在应用程序内执行测试的测试框架。它确保一切工作正常。
在Node.js中使用Mocha意味着在Node.js运行时环境中使用mocha单元测试框架。Mocha具有许多强大功能。
关键特性:
- 简单的异步支持。
- 异步测试超时支持。
- 使用任何你想要的断言库。
- before、after、before each、after each钩子对于在每个测试中清理环境非常有用。
如果你对 mongoose 不熟悉,请点击这里。
在一段时间内,我们的应用程序测试代码行数将超过实际应用程序逻辑代码行数。所以编写测试并遵循测试驱动开发或TDD方法始终是一件好事。
在本文中,我们将设置一个基本的测试套件,使用最流行的Mocha测试框架,对MongoDB数据集使用Mongoose库进行创建、读取、更新和删除(CRUD)操作。
安装模块:
npm i mocha mongoose
文件夹结构:
我们将在测试目录中创建所有的测试文件。
在我们的Node.js-MongoDB项目中,我们将使用这个帮助文件来创建连接。如果您是MongoDB的新手,请参阅这篇文章。
test_helper.js
// test/test_helper.js
const mongoose = require('mongoose');
// tells mongoose to use ES6 implementation of promises
mongoose.Promise = global.Promise;
const MONGODB_URI = 'mongodb://mongodb0.example.com:27017';
mongoose.connect(MONGODB_URI);
mongoose.connection
.once('open', () => console.log('Connected!'))
.on('error', (error) => {
console.warn('Error : ', error);
});
// runs before each test
beforeEach((done) => {
mongoose.connection.collections.users.drop(() => {
done();
});
});
我们将使用beforeEach()钩子在测试运行之前清空我们的数据库。删除需要时间,因此我们需要在操作完成之前暂停mocha的执行。调用done()函数表示操作现在已经完成,我们可以继续执行。
.on()和.once()是事件处理程序。它们将事件作为第一个参数,将一个在事件发生时执行的函数作为第二个参数。
我们的MongoDB架构:
user.js
// Inside schema/user.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: [true, 'Name is required.']
},
age: Integer
})
// it represents the entire collection of User data
const User = mongoose.model('User', UserSchema);
module.exports = User;
现在,我们需要在package.json文件中添加一个脚本来启动测试。
"scripts": {
"test" : "mocha --recursive --exit"
}
在“-recursive”意味着它将在测试目录内进行递归测试,“-exit”表示一旦所有测试都已执行完毕就退出。使用以下命令来使用Mocha运行测试。
npm run test
Mocha提供了一个describe()函数,它接受一个字符串作为第一个参数,用于标识正在通过或失败的测试组,测试逻辑被实现为describe()的第二个参数中的函数。
describe()可以包含多个测试,它们可以在it()方法中或嵌套的describe()函数中。在我们的案例中,我们将为MongoDB中的每个CRUD操作创建不同的文件。或者,我们也可以使用一个包含不同的describe块的单个文件。
每个测试都需要断言,Mocha允许我们使用许多断言库。在这里,我们将使用Node.js内置的assert模块。
通过在测试回调的it()中添加done(),Mocha将知道该测试已经完成。
create_test.js
//import the User model
const User = require('../schema/user');
const assert = require('assert');
describe('Creating documents in MongoDB', () => {
it('Creates a New User', (done) => {
const newUser = new User({ name: 'Shriyam' });
newUser.save() // returns a promise after some time
.then(() => {
//if the newUser is saved in db and it is not new
assert(!newUser.isNew);
done();
});
});
});
read_test.js
const User = require('../schema/user');
const assert = require('assert');
let user;
// this will run before running every test
beforeEach(() => {
// Creating a new Instance of User Model
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
describe('Reading Details of User', () => {
it('Finds user with the name', (done) => {
User.findOne({ name: 'Shriyam' })
.then((user) => {
assert(user.name === 'Shriyam');
done();
});
})
})
delete_test.js
const User = require('../schema/user');
const assert = require('assert');
describe('Deleting a User', () => {
let user;
beforeEach((done), () => {
// user is an instance of User Model
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
it('Removes a User using its instance', (done) => {
User.remove()
// Checking if the user was deleted from DB or not
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
});
it('Removes a user', (done) => {
User.findOneAndRemove({ name: 'Shriyam' })
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
});
it('Removes a user using its id', (done) => {
User.findIdAndRemove(user._id)
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
})
})
update_test.js
const Username = require('../schema/user');
const assert = require('assert');
describe('Deleting a user', () => {
let user;
beforeEach((done) => {
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
// Handling Redundant Code
function helperFunc(assertion, done) {
assertion
.then(() => User.find({}))
.then((users) => {
assert(users.length === 1);
assert(users[0].name === 'Updated Shriyam');
done();
});
}
it('Sets and saves a user using an instance', (done) => {
// Not yet updated in MongoDb
user.set('name', 'Updated Shriyam');
helperFunc(user.save(), done);
});
it('Update a user using instance', (done) => {
helperFunc(user.update({ name: 'Updated Shriyam' }), done);
});
});
所以,我们现在学习了如何使用Mocha和Mongoose创建单元测试。
提示: 使用 mockgoose 库来使用一个虚拟的MongoDB数据库,以使你的原始数据库保持干净。