带有猫鼬调用的摩卡测试功能
mocha test function with mongoose call
在对以下代码进行单元测试时遇到一些问题,由于其编码方式,我不确定是否可行。
storeModel.js
var storeSchema = new Schema({
storeId : { type: String, index: true},
storeName : String
});
var model = mongoose.model('store', storeSchema);
var findStoresById = function(ids, callback) {
model.find({ storeId: { $in: ids }}, function (err, result) {
if (err) callback(err);
callback(err, result);
});
};
return {
findStoresById: findStoresById,
schema: storeSchema,
model: model
};}();
我是这样测试的..
it('will call "findStoresById" and return matched values [storeId: 1111] ', function (done) {
storeModel.findStoresById(['1111'], function(err, store) {
assert.equal(store[0].storeId, '1111');
assert.equal(store[0].storeName, 'StoreName');
assert.equal(err, null);
done();
});
});
然而,当我在单独的函数中实现以下代码时出现问题:
get: function (req, res) {
if (req.query.storeIds) {
var ids = req.query.storeIds.split(',');
storeModel.findStoresById(ids, function(err, stores) {
if (err) {
return res.send(err);
}
if (_.isEmpty(stores)) {
var error = {
message: "No Results",
errorKey: "XXXX"
}
return res.status(404).json(error);
}
return res.json(stores);
}); ...
我如何对此进行单元测试,我不想嘲笑它,因为 "findStoreById" 中的某些功能需要测试,或者是否需要重构?建议?
我认为你实际上应该存根 findStoreById
因为不这样做 get
不能严格地进行单元测试,因为它不是孤立的并且可能因自身的错误而失败.鉴于您要测试的功能位于 findStoreById
的回调中而不是方法本身,我们可以愉快地存根它并使用 sinon 的 yields
方法相应地调用其回调。
请注意,如果您要测试路由,最好使用 supertest 否则您手上会有很多请求和响应方法的模拟。因此,例如:
var request = require('supertest');
var express = require('express');
// stub database method
sinon.stub(storeModel, 'findStoresById');
// create a test app/route to which we direct test requests
var app = express();
app.get('/', myRouteFunction);
it('sends a 404 error when no stores are found', function(done) {
// use the second argument of `yields` to pass a result to the callback
storeModel.findStoresById.yields(null, []);
request(app).get('/').expect(404, done);
});
it('responds with any stores found', function(done) {
// pass an array of found stores to the callback
storeModel.findStoresById.yields(null, [{_id: 1}]);
request(app).get('/').end(function(err, res) {
if(err) return done(err);
assert.deepEqual(res.body, [{_id: 1}]);
done();
});
});
如果你想要测试某些 Mongoose 模型的 static's
和 method's
,我建议你使用 sinon and sinon-mongoose.
但首先,请为您的代码提供一些提示
var storeSchema = new Schema({
storeId : { type: String, index: true},
storeName : String
});
// 1) If you will callback with the same 'err' and 'result', pass the callback directly
function findStoresById(ids, callback) {
// Instead of this...
this.find({ storeId: { $in: ids } }, function (err, result) {
if (err) callback(err);
callback(err, result);
});
// Use this... it's the same, but shorter
this.find({ storeId: { $in: ids } }, callback);
}
// 2) Declare a static method on your model, instead of export manually (see Monggose documentation for more info)
storeSchema.static('findStoresById', function (ids, callback) {
});
// 3) Create your model after the statics were declared, and use CamelCase
var model = mongoose.model('Store', storeSchema);
// 4) Export just your model
// If you want the model -> var Store = mongoose.model('Store')
// If you want the schema -> var schema = Store.schema
// If you want to call your method -> Store.findStoresById(...)
module.exports = model;
然后,测试方法findStoresById
var sinon = require('sinon');
require('sinon-mongoose');
var Store = mongoose.model('Store');
sinon.mock(Store)
.expects('find').withArgs({ storeId: { $in: ['id1', 'id2'] } })
.yields(null, 'SUCCESS!');
Store.findStoresById(['id1', 'id2'], function (err, res) {
assert(res, 'SUCCESS!');
});
您可以在 sinon-mongoose 存储库中找到有效(和简单)的示例。
在对以下代码进行单元测试时遇到一些问题,由于其编码方式,我不确定是否可行。
storeModel.js
var storeSchema = new Schema({
storeId : { type: String, index: true},
storeName : String
});
var model = mongoose.model('store', storeSchema);
var findStoresById = function(ids, callback) {
model.find({ storeId: { $in: ids }}, function (err, result) {
if (err) callback(err);
callback(err, result);
});
};
return {
findStoresById: findStoresById,
schema: storeSchema,
model: model
};}();
我是这样测试的..
it('will call "findStoresById" and return matched values [storeId: 1111] ', function (done) {
storeModel.findStoresById(['1111'], function(err, store) {
assert.equal(store[0].storeId, '1111');
assert.equal(store[0].storeName, 'StoreName');
assert.equal(err, null);
done();
});
});
然而,当我在单独的函数中实现以下代码时出现问题:
get: function (req, res) {
if (req.query.storeIds) {
var ids = req.query.storeIds.split(',');
storeModel.findStoresById(ids, function(err, stores) {
if (err) {
return res.send(err);
}
if (_.isEmpty(stores)) {
var error = {
message: "No Results",
errorKey: "XXXX"
}
return res.status(404).json(error);
}
return res.json(stores);
}); ...
我如何对此进行单元测试,我不想嘲笑它,因为 "findStoreById" 中的某些功能需要测试,或者是否需要重构?建议?
我认为你实际上应该存根 findStoreById
因为不这样做 get
不能严格地进行单元测试,因为它不是孤立的并且可能因自身的错误而失败.鉴于您要测试的功能位于 findStoreById
的回调中而不是方法本身,我们可以愉快地存根它并使用 sinon 的 yields
方法相应地调用其回调。
请注意,如果您要测试路由,最好使用 supertest 否则您手上会有很多请求和响应方法的模拟。因此,例如:
var request = require('supertest');
var express = require('express');
// stub database method
sinon.stub(storeModel, 'findStoresById');
// create a test app/route to which we direct test requests
var app = express();
app.get('/', myRouteFunction);
it('sends a 404 error when no stores are found', function(done) {
// use the second argument of `yields` to pass a result to the callback
storeModel.findStoresById.yields(null, []);
request(app).get('/').expect(404, done);
});
it('responds with any stores found', function(done) {
// pass an array of found stores to the callback
storeModel.findStoresById.yields(null, [{_id: 1}]);
request(app).get('/').end(function(err, res) {
if(err) return done(err);
assert.deepEqual(res.body, [{_id: 1}]);
done();
});
});
如果你想要测试某些 Mongoose 模型的 static's
和 method's
,我建议你使用 sinon and sinon-mongoose.
但首先,请为您的代码提供一些提示
var storeSchema = new Schema({
storeId : { type: String, index: true},
storeName : String
});
// 1) If you will callback with the same 'err' and 'result', pass the callback directly
function findStoresById(ids, callback) {
// Instead of this...
this.find({ storeId: { $in: ids } }, function (err, result) {
if (err) callback(err);
callback(err, result);
});
// Use this... it's the same, but shorter
this.find({ storeId: { $in: ids } }, callback);
}
// 2) Declare a static method on your model, instead of export manually (see Monggose documentation for more info)
storeSchema.static('findStoresById', function (ids, callback) {
});
// 3) Create your model after the statics were declared, and use CamelCase
var model = mongoose.model('Store', storeSchema);
// 4) Export just your model
// If you want the model -> var Store = mongoose.model('Store')
// If you want the schema -> var schema = Store.schema
// If you want to call your method -> Store.findStoresById(...)
module.exports = model;
然后,测试方法findStoresById
var sinon = require('sinon');
require('sinon-mongoose');
var Store = mongoose.model('Store');
sinon.mock(Store)
.expects('find').withArgs({ storeId: { $in: ['id1', 'id2'] } })
.yields(null, 'SUCCESS!');
Store.findStoresById(['id1', 'id2'], function (err, res) {
assert(res, 'SUCCESS!');
});
您可以在 sinon-mongoose 存储库中找到有效(和简单)的示例。