mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-30 21:40:39 +03:00
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:
parent
2b76d7a492
commit
0b5cfd933f
@ -1,2 +1,3 @@
|
||||
exports.utils = require('./utils');
|
||||
exports.express = require('./express');
|
||||
exports.knex = require('./knex');
|
||||
|
131
core/test/utils/mocks/knex.js
Normal file
131
core/test/utils/mocks/knex.js
Normal 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;
|
@ -120,6 +120,7 @@
|
||||
"matchdep": "2.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mocha": "4.1.0",
|
||||
"mock-knex": "0.4.0",
|
||||
"nock": "9.1.6",
|
||||
"rewire": "3.0.2",
|
||||
"should": "13.2.1",
|
||||
|
12
yarn.lock
12
yarn.lock
@ -3690,6 +3690,10 @@ lodash@^3.10.1, lodash@~3.10.1:
|
||||
version "3.10.1"
|
||||
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:
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-0.9.2.tgz#8f3499c5245d346d682e5b0d3b40767e09f1a92c"
|
||||
@ -4041,6 +4045,14 @@ mocha@^3.1.2:
|
||||
mkdirp "0.5.1"
|
||||
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:
|
||||
version "0.5.14"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.14.tgz#4eb38ff9538b80108ba467a458f3ed4268ccfcb1"
|
||||
|
Loading…
Reference in New Issue
Block a user