如果要测试它,这就是我的方法,首先有一种方法将我的模拟小部件注入小部件服务。我知道有节点劫持, mockery或者类似的东西node-di,他们都有不同的风格,我相信还有更多。选择一个并使用它。
一旦我做对了,我就会用我的模拟小部件模块创建我的小部件服务。然后我做了这样的事情(这是使用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)是我希望它的行为随着每个不同的测试而改变的函数,所以这就是为什么我每次都重置存根。
这也是做类似事情的另一个例子:https://github.com/mozilla-b2g/gaia/blob/16b7f7c8d313917517ec834dbda05db117ec141c/apps/sms/test/unit/thread_ui_test.js#L1614