Sinon猫鼬模型的存根保存实例方法 [英] Stub save Instance Method of Mongoose Model With Sinon

查看:81
本文介绍了Sinon猫鼬模型的存根保存实例方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试用于使用Mongoose模型保存小部件的服务功能.我想在模型上存入save实例方法,但是我找不到一个好的解决方案.我看到了其他建议,但似乎没有一个完整的建议.

I am trying to test a service function I use to save a widget using a Mongoose model. I want to stub out the save instance method on my model, but I cannot figure out a good solution. I have seen other suggestions, but none seem to be complete.

请参阅... 这是我的模特...

// 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数据,创建一个新的小部件,然后使用保存"实例方法保存该小部件.然后,它会根据保存调用的结果回叫传递一个err和doc.

My service is very simple. It accepts some JSON data, creates a new widget, and then saves the widget using the "save" instance method. It then calls back passing an err and doc based on the outcome of the save call.

我只想在调用createWidget({title:'Widget A'})...时进行测试...

I only want to test that when I call createWidget({title: 'Widget A'})...

  • 通过传递给服务函数的数据调用Widget构造函数一次
  • 新创建的小部件对象上的save实例方法被调用一次
  • 额外信用:该保存实例方法以err的null值和文档的{title:'Widget A'}的名称来调用.

为了单独进行测试,我可能需要...

In order to test this in isolation, I would probably need to...

  • 模拟或存根Widget构造函数,以便它将返回我在测试中创建的模拟widget对象.
  • 将模拟小部件对象的保存功能存根,以便我可以控制发生的情况.

我很难弄清楚如何用Sinon来做到这一点.我尝试过SO网页上的几种变体,但是没有运气.

I am having trouble figuring out how to do this with Sinon. I have tried several variations found on the pages of SO with no luck.

注意:

  • 我不想将已经构造的模型对象传递给服务,因为我希望服务是唯一知道"猫鼬的东西.
  • 我知道这不是最大的交易(仅通过集成或端到端测试来对此进行测试,但是找到一种解决方案会很不错.

感谢您可以提供的任何帮助.

Thanks for any help you can provide.

推荐答案

如果要对此进行测试,这就是我的处理方法,首先要有一种方法将模拟的窗口小部件注入到窗口小部件服务中.我知道有 node-hijack node-di 之类的东西,他们都有不同的风格,我敢肯定还有更多.选择一个并使用它.

If were to test that, this is how I would approach it, first have a way to inject my mocked widget to the widget-service. I know there's node-hijack, mockery or something like node-di, they all have different styles, I'm sure there's more. Choose one and use it.

一旦确定正确,就可以使用模拟小部件模块创建小部件服务.然后我做类似的事情(这是使用 mocha btw):

Once I get that right, then I create my widget-service with my mock widget module. Then I do something like this(this is using mocha btw):

// Either do this:
saveStub = sinon.stub();
function WidgetMock(data) {
    // some mocking stuff
    // ...
    // Now add my mocked stub.
    this.save = saveStub;
}


// or do this:
WidgetMock = require('./mocked-widget');
var saveStub = sinon.stub(WidgetMock.prototype, 'save');


diInject('widget', WidgetMock); // This function doesn't really exists, but it should
// inject your mocked module instead of real one.

beforeEach(function () {
    saveStub.reset(); // we do this, so everytime, when we can set the stub only for
    // that test, and wouldn't clash with other tests. Don't do it, if you want to set
    // the stub only one time for all.
});
after(function () {
    saveStub.restore();// Generally you don't need this, but I've seen at times, mocked
    // objects clashing with other mocked objects. Make sure you do it when your mock
    // object maybe mocked somewhere other than this test case.
});
it('createWidget()', function (done) {
    saveStub.yields(null, { someProperty : true }); // Tell your stub to do what you want it to do.
    createWidget({}, function (err, result) {
        assert(!err);
        assert(result.someProperty);
        sinon.assert.called(saveStub); // Maybe do something more complicated. You can
        // also use sinon.mock instead of stubs if you wanna assert it.
        done();
    });
});
it('createWidget(badInput)', function (done) {
    saveStub.yields(new Error('shhoo'));
    createWidget({}, function (err, result) {
        assert(err);
        done();
    });
});

这只是一个示例,我的测试有时会变得更加复杂.碰巧在大多数情况下,我要模拟的后端调用函数(在这里是widget.save)是我希望其行为随每个不同的测试而改变的函数,因此这就是我每次都要重置存根的原因

This is just a sample, my tests sometimes get more complicated. It happens that most of the time, the backend calling function(here it is, widget.save) that I want to mock, is the one that I want it's behavior to change with every different test, so that's why I reset the stub everytime.

这也是做类似事情的另一个示例: https://github.com/mozilla-b2g/gaia/blob/16b7f7c8d313917517ec834dbda05db117ec141c/apps/sms/test/unit/thread_ui_test.js#L1614

Here's also another example for doing similar thing: https://github.com/mozilla-b2g/gaia/blob/16b7f7c8d313917517ec834dbda05db117ec141c/apps/sms/test/unit/thread_ui_test.js#L1614

这篇关于Sinon猫鼬模型的存根保存实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆