我正在尝试使用Mongoose模型测试我用来保存小部件的服务功能 . 我想在我的模型上存根保存实例方法,但我无法找到一个好的解决方案 . 我见过其他建议,但似乎都没有完整 .
这是我的模特......
// widget.js
var mongoose = require('mongoose');
var widgetSchema = mongoose.Schema({
title: {type: String, default: ''}
});
var Widget = mongoose.model('Widget', widgetSchema);
module.exports = Widget;
这是我的服务......
// widgetservice.js
var Widget = require('./widget.js');
var createWidget = function(data, callback) {
var widget = new Widget(data);
widget.save(function(err, doc) {
callback(err, doc);
});
};
我的服务很简单 . 它接受一些JSON数据,创建一个新的小部件,然后使用“save”实例方法保存小部件 . 然后它根据保存调用的结果回调传递错误和doc .
当我调用createWidget时,我只想测试它({title:'Widget A'})...
-
使用传递给服务函数的数据调用Widget构造函数一次
-
新创建的窗口小部件对象上的save实例方法被调用一次
-
EXTRA CREDIT:保存实例方法为错误调用null,为文档调用{title:'Widget A'} .
为了单独测试这个,我可能需要......
-
模拟或存根Widget构造函数,以便它返回我作为测试的一部分创建的模拟小部件对象 .
-
存储模拟小部件对象的保存功能,以便我可以控制发生的事情 .
我无法弄清楚如何用Sinon做到这一点 . 我已经尝试过在SO页面上找到的几个变种而没有运气 .
笔记:
-
我不想将已构造的模型对象传递给服务,因为我希望服务是"knows"关于mongoose的唯一内容 .
-
我知道这不是最大的交易(只是通过更多的集成或端到端测试来测试它,但是找出解决方案会很好 .
感谢您的任何帮助,您可以提供 .
3 回答
如果要测试它,这就是我接近它的方法,首先要有一种方法将我的模拟小部件注入到widget-service中 . 我知道有node-hijack,mockery或类似于node-di的东西,它们都有不同的风格,我更多 . 选择一个并使用它 .
一旦我做对了,然后我用我的模拟小部件模块创建我的小部件服务 . 然后我做这样的事情(这是使用mocha顺便说一句):
这只是一个例子,我的测试有时会变得更复杂 . 它发生在大多数情况下,我想要模拟的后端调用函数(这里是widget.save)是我希望它的行为随着每个不同的测试而改变的,所以这就是我每次重置存根的原因 .
这也是做类似事情的另一个例子:https://github.com/mozilla-b2g/gaia/blob/16b7f7c8d313917517ec834dbda05db117ec141c/apps/sms/test/unit/thread_ui_test.js#L1614
我就是这样做的 . 我正在使用Mockery来操纵模块加载 . 必须更改
widgetservice.js
的代码,以便在没有.js
扩展名的情况下调用require('./widget');
. 如果没有修改,以下代码将无法工作,因为我使用了避免require
调用中的扩展的一般建议做法 . Mockery明确指出传递给require
调用的名称必须完全匹配 .测试运动员是Mocha .
代码如下 . 我在代码本身中添加了大量的注释 .
除非我错过了什么,否则这涵盖了问题中提到的所有测试 .
使用当前版本的Mongoose,您可以使用
create
方法然后测试方法(使用Mocha)
另外,如果要模拟链式方法,请使用sinon-mongoose .