gpt4 book ai didi

javascript - node.js - 在 mongodb 单元测试上应用 sinon

转载 作者:太空宇宙 更新时间:2023-11-03 23:25:22 26 4
gpt4 key购买 nike

我使用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 的博客,但很难理解和区分它们。我如何将它们应用到这些测试中?

最佳答案

您当前编写的是集成测试,用于测试 Node 服务器和 mongo db 数据库之间的交互。尽管这些测试比模拟单元测试更耗时,但它们实际上提供了更多的值(value)。针对稳定的 MongoDB 实例运行查询可确保您的查询按计划运行,并且您的应用程序正确响应结果,请参阅:How to unit test a method which connects to mongo, without actually connecting to mongo? .

如果您希望测试操作数据的 JavaScript 函数,而不是服务器和数据库之间的交互。我建议您从 mongodb 查询逻辑中重构此代码并对其进行单元测试。或者,当您使用类时,您应该能够使用模拟数据库库覆盖 _db 属性。这只是一个对象,其方法模仿您当前使用的 mongo 库的方法。或者您可以使用 sinon 来删除这些方法,并将它们替换为返回已知结果的方法,请参阅 http://sinonjs.org/releases/v1.17.7/stubs/

尝试这样的事情:

var ensureIndex = { ensureIndex: sinon.stub() }
sinon.stub(db, 'collection').returns(ensureIndex)

var blackList;

describe('Model: Blacklist', () => {

beforeEach(() => {
var blackList = new BlacklistModel(db, id, logger);
})
it('test' => {
blackList.create(data).then(() => {
// some test here
db.collection.calledWithMatch('some match')
})

})
})

关于javascript - node.js - 在 mongodb 单元测试上应用 sinon,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45025030/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com