Added knex mock for unit testing

no issue

- added https://github.com/colonyamerican/mock-knex as dev dependency
- the mock serves our data generator test data by default
  - but you can define your own if you want
- we need a proper mock for unit testing
- we should not mock bookshelf if possible, otherwise we can't test event flows
This commit is contained in:
kirrg001 2018-02-15 20:14:30 +01:00 committed by Katharina Irrgang
parent 2b76d7a492
commit 0b5cfd933f
4 changed files with 145 additions and 0 deletions

View File

@ -1,2 +1,3 @@
exports.utils = require('./utils'); exports.utils = require('./utils');
exports.express = require('./express'); exports.express = require('./express');
exports.knex = require('./knex');

View File

@ -0,0 +1,131 @@
'use strict';
const mockKnex = require('mock-knex'),
_ = require('lodash'),
DataGenerator = require('../fixtures/data-generator'),
knex = require('../../../server/data/db').knex;
/**
* Knex mock. The database is our Datagenerator.
* You can either self register queries or you simply rely on the data generator data.
*
* Please extend if you use-case does not work.
*/
class KnexMock {
initialiseDb() {
this.db = {};
_.each(_.pick(DataGenerator.Content, ['posts', 'users', 'tags', 'permissions', 'roles']), (objects, tableName) => {
this.db[tableName] = [];
_.each(objects, (object) => {
const lookup = {
users: DataGenerator.forKnex.createUser,
posts: DataGenerator.forKnex.createPost,
tags: DataGenerator.forKnex.createTag,
permissions: DataGenerator.forKnex.createPermission,
roles: DataGenerator.forKnex.createRole,
};
this.db[tableName].push(lookup[tableName](object));
});
});
}
mock(options) {
options = options || {autoMock: true};
mockKnex.mock(knex);
this.initialiseDb();
this.tracker = mockKnex.getTracker();
this.tracker.install();
if (options.autoMock) {
this.tracker.on('query', (query) => {
if (query.method === 'select') {
if (query.bindings.length && query.sql.match(/where/)) {
query.sql = query.sql.replace(/`/g, '"');
const tableName = query.sql.match(/from\s\"(\w+)\"/)[1],
where = query.sql.match(/\"(\w+)\"\s\=\s\?/)[1],
value = query.bindings[0],
dbEntry = _.find(this.db[tableName], ((existing) => {
if (existing[where] === value) {
return true;
}
}));
if (dbEntry) {
query.response([dbEntry]);
} else {
query.response([]);
}
}
} else if (query.method === 'insert') {
query.sql = query.sql.replace(/`/g, '"');
const tableName = query.sql.match(/into\s\"(\w+)\"/)[1];
let keys = query.sql.match(/\(([^)]+)\)/)[1],
entry = {};
keys = keys.replace(/"/g, '');
keys = keys.replace(/\s/g, '');
keys = keys.split(',');
_.each(keys, (key, index) => {
entry[key] = query.bindings[index];
});
if (!this.db[tableName]) {
this.db[tableName] = [];
}
this.db[tableName].push(entry);
query.response(entry);
} else if (query.method === 'update') {
query.sql = query.sql.replace(/`/g, '"');
const tableName = query.sql.match(/update\s\"(\w+)\"/)[1],
where = query.sql.match(/where\s\"(\w+)\"\s\=\s\?/)[1],
value = query.bindings.slice(-1)[0],
dbEntry = _.find(this.db[tableName], ((existing) => {
if (existing[where] === value) {
return true;
}
}));
if (!dbEntry) {
query.reject(new Error('not found'));
} else {
let keys = query.sql.match(/set(.*)where/)[1],
entry = {};
keys = keys.match(/\"\w+\"/g).join(',');
keys = keys.replace(/"/g, '');
keys = keys.replace(/\s/g, '');
keys = keys.split(',');
_.each(keys, (key, index) => {
entry[key] = query.bindings[index];
dbEntry[key] = entry[key];
});
query.response(entry);
}
} else {
query.reject(new Error('not implemented.'));
}
});
}
return this.tracker;
}
unmock() {
this.tracker.uninstall();
mockKnex.unmock(knex);
}
}
module.exports = KnexMock;

View File

@ -120,6 +120,7 @@
"matchdep": "2.0.0", "matchdep": "2.0.0",
"minimist": "1.2.0", "minimist": "1.2.0",
"mocha": "4.1.0", "mocha": "4.1.0",
"mock-knex": "0.4.0",
"nock": "9.1.6", "nock": "9.1.6",
"rewire": "3.0.2", "rewire": "3.0.2",
"should": "13.2.1", "should": "13.2.1",

View File

@ -3690,6 +3690,10 @@ lodash@^3.10.1, lodash@~3.10.1:
version "3.10.1" version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
lodash@^4.14.2:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
lodash@~0.9.2: lodash@~0.9.2:
version "0.9.2" version "0.9.2"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-0.9.2.tgz#8f3499c5245d346d682e5b0d3b40767e09f1a92c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-0.9.2.tgz#8f3499c5245d346d682e5b0d3b40767e09f1a92c"
@ -4041,6 +4045,14 @@ mocha@^3.1.2:
mkdirp "0.5.1" mkdirp "0.5.1"
supports-color "3.1.2" supports-color "3.1.2"
mock-knex@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/mock-knex/-/mock-knex-0.4.0.tgz#32c4ed97ff7cf9c86eca2400902f34e1f7f88de1"
dependencies:
bluebird "^3.4.1"
lodash "^4.14.2"
semver "^5.3.0"
moment-timezone@0.5.14: moment-timezone@0.5.14:
version "0.5.14" version "0.5.14"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.14.tgz#4eb38ff9538b80108ba467a458f3ed4268ccfcb1" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.14.tgz#4eb38ff9538b80108ba467a458f3ed4268ccfcb1"