【发布时间】:2017-12-14 22:54:21
【问题描述】:
我用node-mongodb-native为mongodb实现了一个模型函数:
'use strict';
const mongo = require('mongodb');
class BlacklistModel {
constructor(db, tenant_id, logger) {
this._db = db;
this._table = 'blacklist_' + tenant_id;
this._logger = logger;
}
create(data) {
return new Promise((resolve, reject) => {
const options = {
unique: true,
background: true,
w: 1
};
this._db.collection(this._table).ensureIndex({ phone: 1 }, options, (err) => {
if (err) {
this._logger.error(err);
reject(err);
} else {
const datetime = Date.parse(new Date());
data._id = new mongo.ObjectID().toString();
data.createdAt = datetime;
data.updatedAt = datetime;
this._db.collection(this._table).insertOne(data, (err) => {
if (err) {
this._logger.error(err);
reject(err);
} else {
resolve(data);
}
});
}
});
});
}
}
module.exports = BlacklistModel;
现在我想为它编写单元测试,考虑 3 种情况:
- 插入成功
- 由于违反唯一索引而失败
- 由于失去连接而失败
考虑到这些,这是我的测试:
'use strict';
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const expect = chai.expect;
const BlacklistModel = require('../../model/blacklist');
const mongo_url = require('../../config/mongodb');
const MongoClient = require('mongodb').MongoClient;
const logger = require('../../config/logger');
const data = {
name: 'admin'
};
describe('Model: Blacklist', () => {
let Blacklist;
let connected = false;
let test_db;
const connect = () => new Promise((resolve, reject) => {
MongoClient.connect(mongo_url, (err, db) => {
if (err) {
reject(err);
} else {
Blacklist = new BlacklistModel(db, 'test', logger);
connected = true;
test_db = db;
resolve();
}
});
});
before(() => connect());
describe('create', () => {
let id;
beforeEach(() => connected ?
null : connect());
it('Should return an inserted document', () => {
return Blacklist.create(data).then(
(result) => {
expect(result._id).to.be.a('string');
expect(result.name).to.equal(data.name);
expect(result.createdAt).to.be.a('number');
expect(result.updatedAt).to.be.a('number');
id = result._id;
});
});
it('Should fail to insert a blacklist with the same name', () => {
const promise = Blacklist.create(data).then(
(result) => {
id = result._id;
return Blacklist.create(data);
});
return expect(promise).to.be.rejected;
});
it('Should fail due to lost connection', () => {
return test_db.close(true).then(() => {
connected = false;
return expect(Blacklist.create(data)).to.be.rejected;
});
});
afterEach(() => connected ?
Blacklist.delete(id) : connect().then(() => Blacklist.delete(id)));
});
});
我在测试中调用真正的函数,在我看来,这在运行时看起来很尴尬且耗时,以避免副作用。但是目前除了更改测试数据库之外,我还没有提出任何其他想法。有没有办法使用sinon?我已经阅读了几篇关于sinon、spy、stub 和 mock 的博客,但很难理解和区分它们。我如何将它们应用到这些测试中?
【问题讨论】:
标签: javascript node.js mongodb unit-testing sinon