@lykmapipo/mongoose-test-helpers
Version:
mongoose test helpers
107 lines (84 loc) • 2.37 kB
JavaScript
/* eslint-disable */
// TODO: submit fix to https://github.com/underscopeio/sinon-mongoose
import sinon from 'sinon';
import mongoose from 'mongoose';
let MethodTypes = Object.freeze({
aggregate: 'aggregate',
populate: 'populate',
query: 'query',
});
function getMethodType(method) {
const methodType = MethodTypes[method];
return methodType || MethodTypes.query;
}
function chainMethod(type, object) {
let mockType;
switch (type) {
case MethodTypes.aggregate:
mockType = new mongoose.Aggregate();
break;
case MethodTypes.populate:
mockType = object;
break;
default:
mockType = new mongoose.Query();
break;
}
return function chain(method) {
let queryMock = sinon.mock(mockType);
this.owner.chainedMock = queryMock;
makeChainable(queryMock, object, type);
makeChainableVerify(queryMock);
this.returns(queryMock.object);
return queryMock.expects(method);
};
}
function makeChainable(mock, object, mockType) {
let expectsMethod = mock.expects;
mock.expects = function (method) {
mockType = mockType || getMethodType(method);
let expectation = expectsMethod.apply(mock, arguments);
expectation.owner = mock;
expectation.chain = chainMethod(mockType, object).bind(expectation);
return expectation;
};
}
function makeChainableVerify(mockResult) {
let originalVerify = mockResult.verify;
function chainedVerify() {
originalVerify.call(mockResult);
if (mockResult.chainedMock) {
mockResult.chainedMock.verify();
}
}
mockResult.verify = chainedVerify;
}
let oldMock = sinon.mock;
let newMock = function mock(object) {
let mockResult = oldMock.apply(this, arguments);
if (
object &&
(object instanceof mongoose.Model ||
object.schema instanceof mongoose.Schema)
) {
makeChainable(mockResult, object);
makeChainableVerify(mockResult);
}
return mockResult;
};
sinon.mock = newMock;
function sandboxMock(object) {
let mockResult = oldMock.apply(null, arguments);
if (
object &&
(object instanceof mongoose.Model ||
object.schema instanceof mongoose.Schema)
) {
makeChainable(mockResult, object);
makeChainableVerify(mockResult);
}
return mockResult;
}
// Sandbox.prototype.mock = sandboxMock;
// sinon.sandbox.mock = sandboxMock;
sinon.mock = sandboxMock;