Giter Site home page Giter Site logo

mock-knex's Introduction

mock-knex

A mock knex adapter for simulating a database during testing, especially useful when used in combination with fixture-factory.

Knex Support

Currently tested on knex 0.8 through 3.0, should operate on any version of knex but may have issues with untested releases. Please file an issue if you come across any issues.

Installation

$ npm install mock-knex --save-dev

Usage

for Mocking Knex

var knex = require('knex');
var mockDb = require('mock-knex');
var db = knex({
    client: 'sqlite',
});

mockDb.mock(db);

... run tests ...

for Unmocking

... run tests ...

mockDb.unmock(db);

for Tracking queries with knex

... mock knex ...

var tracker = require('mock-knex').getTracker();

tracker.install();

tracker.on('query', function checkResult(query) {
  expect(query.method).to.equal('first');
  query.response([
    {
      fielda : 'A',
      fieldb : 'B'
    },
    {
      fielda : 'C',
      fieldb : 'D'
    },
    {
      fielda : 'E',
      fieldb : 'F'
    }
  ]);
});

knex.table('table').first('fielda', 'fieldb').then(function checkFirstArrResults(model) {
  expect(model.fielda).to.equal('A');
  expect(model.fieldb).to.equal('B');
  tracker.uninstall();
  done();
});

for Tracking queries with Bookshelf

... mock knex ...

var tracker = require('mock-knex').getTracker();

tracker.install();

tracker.on('query', function sendResult(query) {
  query.response([
    {
      id : 1,
      foo : 'bar'
    }
  ]);
});

Model.forge({ id : 1 }).fetch()
  .then(function fetchResult(model) {
    expect(model).to.be.an.instanceof(Model);
    expect(model.get('id')).to.equal(1);
    expect(model.get('foo')).to.equal('bar');
    tracker.uninstall();
    done();
  });

for Tracking multiple successive queries

... mock knex ...
... enable tracking ...

tracker.on('query', function sendResult(query, step) {
  [
    function firstQuery() {
      expect(query.sql).to.equal(... some SQL string ...);
      query.response([{id: 1}]);
    },
    function secondQuery() {
      expect(query.sql).to.equal(... some SQL string ...);
      query.response([{id: 2}]);
    }
  ][step - 1]();
});

More Examples?

Checkout the Tests

API

require('mock-knex')

Method Arguments Returns Description
mock(knex)
knex
initialized knex client
- Attaches mocked client to knex instance
unmock(knex) - Detaches mocked client from knex instance
getTracker() - Tracker Returns query Tracker instance

Tracker

The tracker enables you to catch and respond to queries that occur during testing, see Test for more examples.

Method Arguments Returns Description
install() - - Enables query tracking mock on mocked knex client
uninstall() - - Disables query tracking mock on mocked knex client. Also resets 'step' counter.
on('query', callback(query, step))
callback
A function that gets executed on 'query' event.
query
Query Details object
step
Query execution call counter starting from 1. Increases after every 'query' event emitting. Gets resetted on calling uninstall().
- Add event listener for 'query' event. It gets executed for each query that should end up in database. Instead of this callback gets executed and its up to you to assert queries and mock database responses.

Query Details

The object containing query details that is being sent to knex database dialect on query execution. Object properties signature matches with knex toSQL() output with additional method returns(values).

Property / Method Arguments Returns Description
bindings Array SQL query parameters
method String Method name to be executed (e.g. 'select', 'update', 'delete', 'commit', 'rollback' adn etc.).
sql String Parameterized SQL query string to be executed. Look
options Object Unknown purpose
transacting Boolean Whether or not the query was executed from within a transaction
reject(Error)
Error
The Error, string or instance of Error, which represents why the result was rejected
- Function that needs to be called to mock database query result for knex.
response(values, options)
values
An array of mock data to be returned by database. For Bookshelf this is mostly array of objects. Knex could return any type of data.
options
stream
Is this a stream response, defaults to false
- Function that needs to be called to mock database query result for knex.

Running Tests

$ npm install
$ docker-compose up -d
$ make test-suite

mock-knex's People

Contributors

anpfeff avatar bbeesley avatar bosgood avatar capellini avatar codisredding avatar colmaengus avatar dependabot[bot] avatar devinclark avatar djmc avatar fbarril avatar icgood avatar jbrumwell avatar joshthewanderer avatar jsdevel avatar jwdotjs avatar lapointexavier avatar mattleff avatar maxarturo avatar rawpixel-vincent avatar slawomirkolodziej avatar techniq avatar vellotis avatar yagolopez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mock-knex's Issues

How to mock already initialized Bookshelf

I want to use your lib to mock my bookshelf models.

I did the following.

var user = require('./user');
var knex = require('knex');
var mockDB = require('mock-knex');
var tracker = mockDB.getTracker();

describe('user model', function() {
  before(function() {
    mockDB.knex.use(knex);
    mockDB.knex.install();
    tracker.install();
  });
});

The models are still not mocked and fire normal queries. Seems like the creation of the bookshelft base model and of the models happens prior the mocking what causes it not to work properly.

What I'm doing wrong here?

Related Models w/ Bookshelf

Hi Guys,

I have a more detailed example of the problem I'm getting with related models with Bookshelf

let driver = require('knex');

let mockDb = require('mock-knex');

let knex = driver({
  dialect: 'sqlite3',
  connection: {
    filename: ':memory:'
  },
  createTableIfNotExists: true,
  useNullAsDefault: true
});

let contentForge, layerForge, slotContentForge, slotForge;

let Slot, slotModel;

let tracker;

knex.schema.createTableIfNotExists('layer', function (table) {
  table.increments();
  table.integer('channel_id');
  table.integer('sequence');
  table.string('name');
  table.integer('pixel_width');
  table.integer('pixel_height');
  table.string('diagonal_size');
}).createTableIfNotExists('content', function (table) {
  table.increments('id').primary();
  table.integer('content_type_id');
  table.string('filename');
  table.string('size');
  table.integer('pixel_width');
  table.integer('pixel_height');
}).createTableIfNotExists('slot', function (table) {
  table.increments('id').primary();
  table.integer('slot_content_id').references('slot_content');
  table.integer('layer_id').references('layer');
  table.integer('schedule_id');
  table.integer('day');
  table.time('start_time');
  table.time('end_time');
  table.integer('priority');
  table.integer('play_through');
  table.integer('locked');
  table.string('source');
}).createTableIfNotExists('slot_content', function (table) {
  table.increments('id').primary();
  table.integer('content_id').references('content');
  table.integer('slot_id').references('slot');
  table.integer('stamp');
})
.then(() => {
  mockDb.mock(knex, '[email protected]');

  tracker = mockDb.getTracker();

  tracker.on('query', function(q) {
    console.log(q);
  });

  let bookshelf = require('bookshelf')(knex);

  let Layer = bookshelf.Model.extend({
    tableName: 'layer'
  });

  let Content = bookshelf.Model.extend({
    tableName: 'content'
  });

  let SlotContent = bookshelf.Model.extend({
    tableName: 'slot_content',
    defaults: function() {
      return {
        stamp: '0'
      };
    }
  });

  Slot = bookshelf.Model.extend({
    tableName: 'slot',
    layer: function() {
      return this.belongsTo(Layer, 'layer_id');
    },

    available_contents: function() {
      let contents = this.belongsToMany(Content).through(SlotContent);
      return contents;
    },

    default_content: function() {
      let defaultContent = this.belongsTo(Content).through(SlotContent, 'slot_content_id');
      return defaultContent;
    }
  });

  contentForge = Content.forge({
    id: 1,
    content_type_id: 1,
    filename: 'test.zip',
    size: '12mb',
    pixel_width: 1920,
    pixel_height: 1080
  });

  slotContentForge = SlotContent.forge({
    id: 1,
    content_id: 1,
    slot_id: 1,
    stamp: 8
  });

  layerForge = Layer.forge({
    id: 1,
    channel_id: 1,
    sequence: 1,
    name: 'Test Layer',
    pixel_width: 1920,
    pixel_height: 1080,
    diagonal_size: '32"'
  });

  slotForge = Slot.forge({
    id: 1,
    slot_content_id: 1,
    layer_id: 1,
    schedule_id: 1,
    day: 1,
    start_time: '00:00:00',
    end_time: '00:01:00',
    priority: 1,
    play_through: 1,
    locked: 0,
    source: 'hq'
  });

  return contentForge.save();
})
.then(() => slotContentForge.save())
.then(() => layerForge.save())
.then(() => slotForge.save())
.then(() => {
  return slotForge.fetch({ withRelated: ['layer', 'available_contents', 'default_content'] })
})
.then(model => {
  console.log(model);
  slotModel = model;
  console.log(model.related('available_contents'));
  let availableContentsModel = slotModel.relations.available_contents;
  console.log(slotModel.relations);
  return availableContentsModel.attach([1]);
})
.then(relatedAvailableContentsCollection => {
  return relatedAvailableContentsCollection
    .fetch()
    .then(relatedAvailableContents => {
      let defaultRelatedContentRecord = relatedAvailableContents.find(relatedAvailableContent => {
        return relatedAvailableContent.attributes.id === 1;
      });

      return slotModel
        .save({ slot_content_id: defaultRelatedContentRecord.pivot.id });
    });
})
.then(() => {
  Slot.fetchAll().then(result => {
    console.log(result);
  }).catch(err => {
    console.error(err);
  });
}).catch(err => {
  console.error(err);
});

I'm really sorry if I'm just misunderstanding how I should be using mock-knex, but I'm wondering if the relationships are being mapped properly.

Consider providing a simple runner abstraction, e.g.

Example:

const createRunner = (queryHandlers) => {
  return (query, step) => {
    console.log({
      step,
      sql: query.sql
    });

    const queryHandler = queryHandlers.shift();

    if (!queryHandler) {
      throw new Error('No query handler for step #' + step + '.');
    }

    queryHandler(query);
  };
};

To be used as such:

test('makes one query', async (assert) => {
  const expectedResult = [
    {
      id: 1,
      name: 'a'
    },
    {
      id: 2,
      name: 'b'
    },
    {
      id: 3,
      name: 'c'
    }
  ];

  const runner = createRunner([
    (query) => {
      assert.is(query.sql, 'select `blog`.* from `blog` where `id` in (?, ?, ?)');

      query.response(expectedResult);
    }
  ]);

  tracker.on('query', runner);

  const result = await getBlogsByBlogIds([1, 2, 3]);

  assert.deepEqual(result, expectedResult);
});

Remove setAdapter()

It seems that mockDb.setAdapter() is only used to determine the version of knex to mock. Since you are already taking in the knex instance, would using knex.VERSION be sufficient, or am I overlooking something?

How to configure the inserted record ID?

I cannot figure out how to set the inserted record ID.

const dataSourceModel = new DataSourceModel({name: 'foo'});

await dataSourceModel.save(null, {
  method: 'insert',
  require: true,
  transacting: transaction
});

Here is what I have tried:

test('inserts record to the database', async (t) => {
  const userId = 1;
  const newRecordId = 2;

  const runner = createRunner([
    (query) => {
      t.true(query.sql === 'BEGIN;');

      query.response([]);
    },
    (query) => {
      t.true(query.sql === 'insert into `data_source` (`name`) values (?)');
      t.deepEqual(query.bindings, ['foo']);

+      query.response(newRecordId);
    },
    (query) => {
      t.true(query.sql === 'insert into `data_source_history` (`action_name`, `data_source_id`, `data_source_name`, `revision_number`, `user_id`) values (?, DEFAULT, ?, ?, ?)');
      t.deepEqual(query.bindings, ['insert', 'foo', 0, userId]);

      query.response([]);
    },
    (query) => {
      t.true(query.sql === 'COMMIT;');

      query.response([]);
    }
  ]);

  tracker.on('query', runner);

  await createDataSource({}, {
    name: 'foo'
  }, {
    authorization: {
      some: () => {}
    },
    userId
  });
});

But this way id remains undefined.

Support knex 0.10

Knex has released 0.10 version 2 weeks ago, but mock-knex still requires up to 0.9. Can we upgrade mock-knex to support 0.10?

Multiple trackers

Hi there,

I think I found an issue while debugging a test case. I noticed that we have multiple tests where each one sets up a new mocked knex connection, but then the results are mixed up. It more or less comes to this:

const knex = require('knex');
const mock = require('mock-knex');
const assert = require('assert');

const connector = (fn) => {
  const instance = knex({
    client: 'pg',
  });

  mock.mock(instance);
  const tracker = mock.getTracker();

  tracker.install();
  tracker.on('query', (query) => {
    query.response(fn(query));
  });

  return instance;
};

const db1 = connector(() => {
  return 1;
});
const db2 = connector(() => {
  return 2;
});

db1.select('foo').from('bar').then(result => {
  console.log(result);
  assert(result === 1);
});
Promise {
  _bitField: 0,
  _fulfillmentHandler0: undefined,
  _rejectionHandler0: undefined,
  _promise0: undefined,
  _receiver0: undefined }
> 2
Unhandled rejection AssertionError [ERR_ASSERTION]: false == true
    at db1.select.from.then.result (repl:3:3)
    at bound (domain.js:301:14)
    at runBound (domain.js:314:12)
    at tryCatcher (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/franco/fiit/workout-api/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:781:20)
    at tryOnImmediate (timers.js:743:5)
    at processImmediate [as _immediateCallback] (timers.js:714:5)

I had a quick look and I think mock.getTracker() should not return a singleton, is that right? Or am I misunderstanding the API in any way?

Add support for stream() interface

Thanks for a great library. It has made life so much easier, unfortunately though the current implementation doesn't seem to support the stream interface available through knex:

var stream = knex.select('id').from('table').stream();
stream.on('data', entry => { 'do something with entry'; });
stream.on('error', error => { 'handle error'; });
stream.on('end', () => { 'handle end' });

Responding with a query.response([]) currently results in TypeError: expecting an array, a promise or a thenable.

mocking .count()

how can I mock .count()?

This is what I've tried. Any suggestions?

return user.where('personId', personId)
  .count('personId')
  .then((count) => [response, count > 0]);

tracker.on('query', (query) => {
  query.response(0);
  tracker.uninstall();
});
160813/015014.665, [error] message: Cannot read property 'count' of undefined stack: TypeError: Cannot read property 'count' of undefined
    at Sync.<anonymous> (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/lib/sync.js:111:21)
    at bound (domain.js:287:14)
    at Sync.runBound (domain.js:300:12)
    at Sync.tryCatcher (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/promise.js:507:31)
    at Promise._settlePromiseAt (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/promise.js:581:18)
    at Async._drainQueue (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:128:12)
    at Async._drainQueues (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (/Users/rocky.assad/src/gbw/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:15:14)

Trouble Returning Null Query Response

I am attempting to setup a test for the getByEmail function below that returns 'null' when my query doesn't find a matching result.

  var getByEmail = promise.method(function (email, embed) {   
    return new User({ email: email }).fetch({ withRelated: embed });
  });

  it('getByEmail should return null when there is not a match in the database', function (done) {
    mockDb.mock(data.knex);
    tracker.install();

    tracker.on('query', function checkResult(query) {
      query.response([
        null
      ]);
    });

    var user = { first_name: 'Bob', last_name: 'Miller', email: '[email protected]' };

    getByEmail(user.email)
     .then(function(result){
       expect(result).to.be.null;
       tracker.uninstall();
       mockDb.unmock(data.knex);
       done();
    });
  });

I hoped that providing a query.response of 'null' would result in 'null' being returned, but when my test runs getByEmail returns an object (shown below) and my 'null' check fails. When I run the method and hit the database directly the same code does return a 'null' result.

ModelBase {
  attributes: { email: '[email protected]' },
  _previousAttributes: { email: '[email protected]' },
  changed: {},
  relations: {},
  cid: 'c1',
  _knex: null }

Any help would be appreciated. Thanks!

confused by usage

I am confused as to how to use mock-knex. My model files and controller files contain references to bookshelf.js file like this:

const Bookshelf = require('../bookshelf').Bookshelf;
const ModelBase = require('../bookshelf').ModelBase;
const Manager = require('../models/manager');

const Result = ModelBase.extend({
  tableName: 'results',
  manager: function() {
    return this.belongsTo(Manager);
  }
});

module.exports = Bookshelf.model('Result', Result);

bookshelf.js looks like this

const config = require('./config/config').config;
const bcrypt = require('bookshelf-bcrypt');

const knex = require('knex');

const connection = knex(config.database);

if(process.env.NODE_ENV === 'test') {
  const mockKnex = require('mock-knex');
  mockKnex.mock(connection, '[email protected]');
}

const bookshelf = require('bookshelf')(connection);
const ModelBase = require('bookshelf-modelbase')(bookshelf);

bookshelf.plugin(['registry', 'bookshelf-camelcase']);
bookshelf.plugin(bcrypt);

module.exports.Bookshelf = bookshelf;

module.exports.ModelBase = ModelBase;

How can I use mock-knex in this scenario?

Also in the docs it says I should use sqlite like this:

var knex = require('knex');
var mockDb = require('mock-knex');
var db = knex({
    client: 'sqlite',
});

Does mock-knex use sqlite? if so, do I need to create the tables and seed the data in the sqlite database?

Add recorder much like nock has.

I was thinking that it would be a useful addition to add a .record() function, that would record the unmocked db calls and output the mock-knex code needed to mock those same calls.

Mocking knex transaction using mock-knex module

Hi,
I want to mock the knex transaction using mock-knex module.

Code:

knex.transaction((trx) => {
knex(tableName)
.transacting(trx)
.forUpdate()
.select('ProductId','ProductName','ProductStatus')
.where({ProductStatus: 'Available'})
.orderBy('DATE_ADDED', 'asc')
.limit(1)
.then((data) => {
return knex(tableName).transacting(trx)
.where(ProductId: data[0].ProductId)
.update({
ProductStatus : "Booked",
});
})
.then(trx.commit)
.catch(trx.rollback);
})
.then((response) => {
console.log('Transaction complete - ', JSON.stringify(response));
})
.catch((error) => {
console.error('Error - ', JSON.stringify(error));
});

Can anyone suggest me how to mock this?

Support for knex 0.14.0

Tried testing with new knex version and received this:

Error: Unable to locate version: 0.14.0
      at MockKnex._extractVersion (node_modules/mock-knex/dist/index.js:65:15)
      at MockKnex._setAdapter (node_modules/mock-knex/dist/index.js:87:24)
      at MockKnex.unmock (node_modules/mock-knex/dist/index.js:116:12)
      at Context.afterEach (tests/tests-initializer.js:23:25)

Knex 0.14.0 changelog: http://knexjs.org/#changelog

I don't know muck about your project, but I'll try to learn and update. Any help is aways accepted :)

Fix ingaia/integration#142

Seeding DB broken after unmocking

I'm seeing a problem with seeding the database with Knex after unmocking. I'd like to be able to start the test suite with Knex mocked and then for some tests that we want to hit the actual database, unmock Knex, seed the database, then run the tests. Afterwards Knex would be re-mocked.

The problem is that after unmocking Knex, seeding seems to be broken. More specifically, queries like the following in the seed file return undefined:

exports.seed = function(knex, Promise) {

  return knex('user')
    .where({ type: 'customer' })
    .returning('id')
    .then(function(user) {
      const userId = user[0].id;

      // The above above throws an error
      // TypeError: Cannot read property '0' of undefined
    });

};

I'm on v0.11.7 of Knex.

Are there any work arounds for this or a fix coming? Thanks.

Incompatible with knex 0.8.3

Steps to reproduce:

$ npm install [email protected]
$ npm test

Mock DB :
  Module
    โœ” 1) should have a getTracker method (4 ms)
    โœ” 2) should return an instance of the tracker (1 ms)
    โœ” 3) should have a knex property (1 ms)
    โœ” 4) should have a knex#install method (0 ms)
    โœ–5) should mock an adapter when called with a name
    โœ–6) should mock an adapter when called with an array of names
    โœ–7) should mock all adapters when called without a name
    โœ” 8) should have a knex#uninstall method (0 ms)
    โœ–9) should revert a single adapter back to the original
    โœ–10) should revert all adapter back to the original
  Tracker
    โœ” 11) should not track if not installed (10 ms)
    โœ–12) should track if installed
    โœ” 13) uninstall should stop tracking (1 ms)
    โœ–14) should return a query object with a response method
    โœ–15) should return a query object with a method property
    โœ–16) should return a query object with a bindings property
    โœ–17) should return a query object with a sql property
    โœ–18) should be able to get the first query
    โœ–19) should be able to get the last query
    โœ–20) should be able to get a query at a specific step
    โœ–21) should pass a step parameters to the query event
    โœ–22) should reply with the data passed to the query#response
    Knex
      โœ–23) should support knex#first method with array response
      โœ–24) should support knex#first method with object response
      โœ–25) should support knex#pluck method with array response
      โœ–26) should support knex#truncate method
      โœ–27) should support knex#del method
      โœ–28) should support knex#stream method
      โœ–29) should catch errors on stream
      โœ–30) should support transactions
    Bookshelf
      Models
        โœ–31) should work with Model#fetch
        โœ–32) should work with Model#fetchAll
        โœ–33) should work with Model#save on updates
        โœ–34) should work with Model#save on inserts
        โœ–35) should work with Model#destroy
      Collections
        โœ–36) should work with Collection#fetch method
        โœ–37) should work with Collection#fetchOne method

issues with error propagating

I'm writing unit tests to handle possible DB errors:

tracker.on('query', (query) => {
    expect(query.method).to.equal('del');
    query.reject(Error('No Rows Deleted'));
});

Later in code when I print error.message of the error propagating it is

   delete from "resource_type" where "id" = $1 - No Rows Deleted

which is query.sql + ' - ' + error.message of what I would expect.
This makes it impossible to test any error handling.

Using mock-knex 0.4.2, knex 0.14.4 and bookshelf 0.13.3

Mocking various scenarios for Mocha

I'm using Bookshelf and trying to mock two different scenarios for a function which sets up an endpoint.

The data passed into the function is the same for both scenarios; the only difference is that in the second scenario, one of the returned objects has a different value for a property that tells us how many endpoints are already registered, which should then trigger an error telling us the limit has been reached.

I've created arrays of mock return functions, and am passing them into the test. Unfortunately, they both trigger the limit error. It feels like I don't understand the way Mock-Knex is loading the arrays.

Here are my return function arrays:

const successfulSetupTokenFetch = () => {
    query.response([{
        'endpoint_limit': 20,
        'endpoints_registered': 1
    }]);
};

const maxEndpointsSetupTokenFetch = () => {
    query.response([{attributes:{
            'endpoint_limit': 20,
            'endpoints_registered': 21
        }
    }]);
};

const successfulNewSetupQueries = [
    successfulSetupTokenFetch,
    ...
];

const endpointLimitSetupQueries = [
    maxEndpointsSetupTokenFetch,
    ...
];

And here are my tests:

describe('Endpoint setup function', function () {
    mockDb.mock(db);
    it('should create and return a new access token when given proper inputs', async function () {
        tracker.install();
        tracker.on('query', function sendResult (query, step) {
            successfulNewSetupQueries[step - 1]();
        });
        const setupReturn = await setupEndpoint(goodSetupObject);
        assert.equal(typeof setupReturn.token, 'string');
        tracker.uninstall()
    });
    it('should return an endpoint limit error when the limit is reached', async function () {
        tracker.install();
        tracker.on('query', function sendResult (query, step) {
            endpointLimitSetupQueries[step - 1]();
        });
        const endpointReturn = await setupEndpoint(goodSetupObject);
        assert.equal(endpointReturn.error, 'Your organization has reached its endpoint limit. P');
        tracker.uninstall();
    });
    mockDb.unmock(db);
});

Please help me understand what I'm doing wrong.

knex.VERSION is deprecated

A recent change to knex.js deprecated use of knex.VERSION, knex/knex@48a2ee1#diff-1fdf421c05c1140f6d71444ea2b27638R46.

As a result, mock-knex is producing the following warnings:

Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ BlogByBlogIdLoader โ€บ before failed with "Unable to locate version: 0.12.0"
Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ BlogByBlogIdLoader โ€บ after failed with "Unable to locate version: 0.12.0"
Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ PostsByBlogIdLoader โ€บ before failed with "Unable to locate version: 0.12.0"
Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ PostsByBlogIdLoader โ€บ after failed with "Unable to locate version: 0.12.0"
Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ UserByUserIdLoader โ€บ before failed with "Unable to locate version: 0.12.0"
Knex:warning - knex.VERSION is deprecated, you can get the module versionby running require('knex/package').version
  โœ– loaders โ€บ UserByUserIdLoader โ€บ after failed with "Unable to locate version: 0.12.0"

TypeError thrown after mocked database save

I'm using mock-knex to mock a knex instance as follows:

var mockknex = require('mock-knex');
var knex = require('knex');
var bookshelf = require('bookshelf');

var knexInstance = knex([...]);
mockknex.mock(knex);

var bookshelfInstance = bookshelf(knex);

The mocked knex instance is then passed to bookshelf so that I can run some tests. However, I eventually get the following error at the end of my tests:

TypeError: Cannot read property '0' of undefined
    at null.<anonymous> (/.../node_modules/bookshelf/lib/model.js:1015:57)

For reference, that line in the bookshelf library can be found here. This does not happen when I do not mock the knex instance, so I wonder if it could be because I'm using this library incorrectly or if there might be a bug.

Mocha + mock-knex : timeout

Hi,

I've encountered an issue with a unit test with your framework :

"use strict";

var mocker = require('mock-knex');
var test = require('unit.js');
var es = require('event-stream');

function _streamToObject(stream, cb) {
    stream.pipe(es.writeArray(cb));
}

describe('Catalog Repo', function () {

    var instance;
    var tracker;

    beforeEach(function () {
        var knex = require('knex');
        mocker.knex.use(knex);
        mocker.knex.install('pg');
        instance = require('../../../src/repos/TestRepo')(knex({
            client: 'pg'
        }), console);
        tracker = mocker.getTracker();
    });

    afterEach(function () {
        mocker.knex.uninstall();
    });

    it('empty items list', function (done) {
        instance.list(undefined, undefined, undefined, function (stream) {
                _streamToObject(stream, function (err, values) {
                test.undefined(err);
                test.isArray(values);
                test.isEmpty(values);
                done();
            });
        });
    });

    it('get a item', function (done) {
        tracker.on('query', function (query) {
            console.log(query);
            query.response([
                {
                    'catalog_id': 1,
                    'name': "TEST",
                    'description': null,
                    'created_at': "10/12/2014",
                    'updated_at': null
                }
            ]);
        });
        instance.get(undefined, 1, function (err, value) {
            test.undefined(err);
            test.isNotEmpty(value);
            done();
        });
    });
});

I obtain this output :

0 passing (4s)
  2 failing

  1) Catalog Repo list empty catalogs:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/Users/guillaumechauvet/Documents/NetBeansProjects/catalogs_rest/master/node_modules/mocha/lib/runnable.js:158:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

  2) Catalog Repo get a catalog:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/Users/guillaumechauvet/Documents/NetBeansProjects/catalogs_rest/master/node_modules/mocha/lib/runnable.js:158:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

Any idea how to resove this kind of issue ?

Not getting response from tracker with bookshelf and mock-knex

I am not getting the response from tracker with mock-knex:

I initalise mock-knex in my bookshelf.js file like this:

const config = require('./config/config').config;
const bcrypt = require('bookshelf-bcrypt');

const knex = require('knex');

const connection = knex(config.database);

if(process.env.NODE_ENV === 'test') {
  const mockKnex = require('mock-knex');
  mockKnex.mock(connection, '[email protected]');
}

const bookshelf = require('bookshelf')(connection);
const ModelBase = require('bookshelf-modelbase')(bookshelf);

bookshelf.plugin(['registry', 'bookshelf-camelcase']);
bookshelf.plugin(bcrypt);

module.exports.Bookshelf = bookshelf;

module.exports.ModelBase = ModelBase;

And the config.js looks like this:


const env = process.env.NODE_ENV || 'development';
const config = {};

switch(env) {
  case 'development':
    config.database = {
      client: 'postgresql',
      connection: {
        host: '127.0.0.1',
        port: 5432,
        user: 'paulcowan',
        database: 'managers',
        charset: 'utf8'
      },
      migrations: {
        tableName: 'knex_migrations'
      }
    }
  case 'test':
    config.database = {
      dialect: 'sqlite3',
      connection: {
        filename: ':memory:'
      },
      createTableIfNotExists: true,
      useNullAsDefault: true
    };
};

config.token = 'secret-jwt-token'
config.site = {
  port: 5000
};

module.exports.config = config;

I then have the following test that creates the tracker:

'use strict';

import should from 'should';
import app from '../../server';
import supertest from 'supertest-as-promised';

import mockKnex from 'mock-knex';

const tracker = mockKnex.getTracker();

tracker.install();

const request = supertest.agent(app.listen());

context('Admin', () => {
  describe('POST /admin', () => {
    before(() => {
      tracker.on('query', (query, step) => {
        query.response({
          id: 1,
          username: 'admin',
          name: 'Paul Cowan',
          password: 'password'
        });
      });
    });

    it('should log a user in', async () => {
      await request
        .post('/auth/')
        .send({username: 'admin', password: 'password'})
        .expect(201)
        .then((err, res) => {
          console.dir(res.body);
        });
    });
  });
});

I am using User.findOne in a passport local method below but if I log the result:


passport.use('local', new Strategy({
  usernameField: 'username',
  passwordField: 'password'
}, async (username, password, done) => {
  try {
    const user = await User.findOne({
      username
    });

    console.dir(user);

    if (!user) {
      return done(null, false)
    }

    try {
      const isMatch = await user.validatePassword(password);

      if (!isMatch) {
        return done(null, false)
      }

      done(null, user)
    } catch (err) {
      done(err)
    }

  } catch (err) {
    return done(err)
  }
}));

It comes back with this:

ModelBase {
  attributes: { username: 'admin' },
  _previousAttributes: { username: 'admin' },
  changed: {},
  relations: {},
  cid: 'c2',
  _knex: null }

So the attributes only has the username. I am confused as to how to properly set this up.

Sequence multiples without Step

Hi, thanks for a really useful library... I'm finding it really great for my current project.

I was looking at the docs, and managed to write some demo tests for multi queries on a sandbox project in order without the step argument. In ES6...

            const queryChain = [
                (query) => {
                    expect(query.method).to.equal('select');
                    query.response({'a': 'b'});
                },
                (query) => {
                    expect(query.method).to.equal('update');
                    query.response({'c': 'd'});
                },
                (query) => {
                    expect(query.method).to.equal('insert');
                    query.response({'e': 'f'});
                }
            ];

            tracker.on('query', (query) => {
                queryChain.shift().call(this, query);
            });

Which I guess could be in ES5 like this -

            var queryChain = [
                function (query) {
                    expect(query.method).to.equal('select');
                    query.response({'a': 'b'});
                },
                function (query) {
                    expect(query.method).to.equal('update');
                    query.response({'c': 'd'});
                },
                function (query) {
                    expect(query.method).to.equal('insert');
                    query.response({'e': 'f'});
                }
            ];

            tracker.on('query', function (query) {
                queryChain.shift().call(this, query);
            });

Tracking `transaction` context

It would be great if transaction context for query could be accessed through tracker event.

The query dialect client has a instance property txid if transaction is used. This can be accessed the same way by query mock.

I would implement it and do a PR, but what would be the best practise to implement it? Set it as tracker emitted query argument property, property of its options proeprty or as an additional event emit argument? I think the last one would be suitable as the query argument is returned by promise. So the new signature for track method would be

Queries.prototype.track = function track(query, trx, resolver) {
  var step;

  if (this.tracker.tracking) {
    query.response = function response(result) {
      query.result = result;
      resolver(query);
    };

    delete query.result;

    step = this.queries.push(query);
    this.tracker.emit('query', query, step, trx);
  } else {
    resolver();
  }
};

And the client query method must be something like this

client.constructor.prototype._query = client._query = function(connection, obj) {
  return new Promise(function(resolver, rejecter) {
    tracker.queries.track(obj, this.txid, resolver);
  });
};

and knex _query method must be something like this

client._query = function(connection, obj) {
  return new Promise(function(resolver, rejecter) {
    tracker.queries.track(obj, this.txid, resolver);
  });
};

As a result the query context trx could be accessible this way:

tracker.on('query', function (query, step, trx) { /* some logic */ };

Is it considerable?
BR

Testing createTable/hasTable

I am trying to create unit tests for functions that accept a table name, check if the table exists, and if not create the table with knex.

When I try something like this pseudocode:

const mockKnex = require('mock-knex');
const fooModule = require('foo-module');
const db = knex({
  client: 'pg',
});
mockKnex.mock(db);

const test = fooModule('test-table', db);
...moar tests...

and fooModule module that has:

module.exports = function (tableName, knex) {
  return knex.schema.hasTable(tableName);
};

I get errors like:

    return knex.schema.hasTable(tableName);
                      ^

TypeError: Cannot read property 'hasTable' of undefined

Is hasTable part of mock-knex? Is createTable?

thank you,
Scott

Api change

Github docs are different from npm (setAdapter)... Maybe worth publishing the change and making a major version change?

Mock-knex 0.3.3 failed on save and update operations

My unit tests worked fine with Mock-knex 0.3.2.
With the last version, I've got this error when I want to test some insert or update operations inside a transaction:

On insert:

Unhandled rejection TypeError: Cannot read property 'insertId' of undefined
    at Client.processResponse (C:\Projets\Front\webapp-internet\node_modules\knex\lib\dialects\mysql\index.js:116:21)
    at C:\Projets\Front\webapp-internet\node_modules\knex\lib\runner.js:116:28
    at tryCatcher (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\util.js:26:23)
    at Promise._settlePromiseFromHandler (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\promise.js:507:31)
    at Promise._settlePromiseAt (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\promise.js:581:18)
    at Async._drainQueue (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:128:12)
    at Async._drainQueues (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

On update:

Unhandled rejection TypeError: Cannot read property 'affectedRows' of undefined
    at Client.processResponse (C:\Projets\Front\webapp-internet\node_modules\knex\lib\dialects\mysql\index.js:120:20)
    at C:\Projets\Front\webapp-internet\node_modules\knex\lib\runner.js:116:28
    at tryCatcher (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\util.js:26:23)
    at Promise._settlePromiseFromHandler (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\promise.js:507:31)
    at Promise._settlePromiseAt (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\promise.js:581:18)
    at Async._drainQueue (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:128:12)
    at Async._drainQueues (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (C:\Projets\Front\webapp-internet\node_modules\knex\node_modules\bluebird\js\main\async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

This is an exemple of code which failed:

bookshelf.transaction(function(t) {
  return Customer.forge(customer)
    .save(null, {
       method: 'insert',
       transacting: t
    }).then(function(insertedCustomer) {                    
        return insertedCustomer.customers().attach(customers, {
           transacting: t
        });
     }).then(function(result) {
          resolve(customer);
     }).catch(function(err) {
           reject(err);
     });
 });

And this is my tracker code:

var customer = [];
var insertedCustomer = {
   id: "TEST",
   name: "TEST"
  };
var customers = ['2', '3', '4'];
tracker.on('query', function sendResult(query) {
  if (query.method === 'select') {
    query.response(customer);
  } else if (query.method === 'insert') {
      if (query.bindings.length === 3) {
         customer.push(insertedCustomer);
         customer[0].customers = [];
       } else {
          customer[0].customers.push(query.bindings[0]);
       }
      query.response(customer);
  } else {
       query.response(customer);
  }
});

emitted `step` argument is not documented

Just to mark it as a issue as I used to solve it by myself with function closure before I investigated how to implement transaction context support.

Example:

// My way
tracker.on('query', (function() {
  var counter = 0;
  return function (query) {
    return [
      function() { /* first query processing */ },
      function() { /* second query processing */ }
    ][counter++]();
  };
})());

// Correct way
tracker.on('query', function (query, step) {
  [
    function() { /* first query processing */ },
    function() { /* second query processing */ }
  ][step - 1]();
});

change port

Hi,

i have an issue that if i have running a docker mysql image in port 3307 for example, when i mock the connection doing:

const knex = require('knex')
const mock = require('mock-knex')
const db = knex({ client: 'mysql' })
mock.mock(db)

always connect to 3306, and if i change the connection like:

const db = knex({ client: 'mysql', connection: { port: 3307 } })

i have the same result when i run the test inside docker. By default always try to connect to port 3306 and if i have a phisical mysql installed to other systems retrieves an error like connection refused because the phiscial mysql have another users that i dont need inside docker msyql image.

Someone maybe know how solve it?

thanks!

Only returns one column from Db table for MSSQL select query

Hi There, I have a simple knex query and when i run the test with mock-knex i am only getting one table field information instead of all fields where as when i run the knex mssql query same code against actual MSSQL Db it returns all table fields. Below attach is the sample query.

 knex
        .from(tableName)
        .where("TEST", "TEST")
        .select()
        .then((objInstance)=>{
           return objInstance
        })

connection.query is not a function

I have a test suite that queries against a postgres running in a docker container. When I run tests using mock-knex before I run my integration tests, all those tests start failing with the following stack:

20) lib/models/Foo "before all" hook:
     TypeError: insert into "users" ("created_at", "password", "updated_at", "username") values ($1, $2, $3, $4) returning "id" - connection.query is not a function
      at /someProject/node_modules/knex/lib/dialects/postgres/index.js:151:18
      at tryCatcher (/someProject/node_modules/knex/node_modules/bluebird/js/main/util.js:26:23)
      at Promise._resolveFromResolver (/someProject/node_modules/knex/node_modules/bluebird/js/main/promise.js:480:31)
      at new Promise (/someProject/node_modules/knex/node_modules/bluebird/js/main/promise.js:70:37)
      at Client._query (/someProject/node_modules/knex/lib/dialects/postgres/index.js:150:12)
      at Client.query (/someProject/node_modules/knex/lib/client.js:127:24)
      at Object.<anonymous> (/someProject/node_modules/knex/lib/runner.js:116:24)
      at Object.tryCatcher (/someProject/node_modules/knex/node_modules/bluebird/js/main/util.js:26:23)
      at Object.query (/someProject/node_modules/knex/node_modules/bluebird/js/main/method.js:15:34)
      at /someProject/node_modules/knex/lib/runner.js:44:21
      at /someProject/node_modules/knex/node_modules/bluebird/js/main/using.js:176:30
      at tryCatcher (/someProject/node_modules/knex/node_modules/bluebird/js/main/util.js:26:23)
      at Promise._settlePromiseFromHandler (/someProject/node_modules/knex/node_modules/bluebird/js/main/promise.js:507:31)
      at Promise._settlePromiseAt (/someProject/node_modules/knex/node_modules/bluebird/js/main/promise.js:581:18)
      at Promise._settlePromises (/someProject/node_modules/knex/node_modules/bluebird/js/main/promise.js:697:14)
      at Async._drainQueue (/someProject/node_modules/knex/node_modules/bluebird/js/main/async.js:123:16)
      at Async._drainQueues (/someProject/node_modules/knex/node_modules/bluebird/js/main/async.js:133:10)
      at Immediate.Async.drainQueues [as _onImmediate] (/someProject/node_modules/knex/node_modules/bluebird/js/main/async.js:15:14)

I'm using the following hooks in mocha everywhere I run tests using mock-knex:

before(function () {
    db = knex({ client: 'postgres' });
    mockDb.mock(db);
    models = modelsFactory({ knex: db, config });
});
after(function () {
    mockDb.unmock(db);
});
beforeEach(function () {
    tracker.install();
});
afterEach(function () {
    tracker.uninstall();
});

Any idea what I should look for?

The following versions are in play:

  • nodejs v4.2.2
  • bookshelf 0.9.1
  • knex 0.9.0
  • mock-knex 0.3.0

Better promise support

I think there's an opportunity to embrace promises more in the tracker:

https://github.com/colonyamerican/mock-knex/blob/master/lib/platforms/knex/0.9/client.js#L30

It would be nice if you were able to just return a promise of the value, instead of having to pass it to the callback. And how about simulating an error? You don't have access to the reject method from the event handler tracker.on('query', ...).

I think that it can be done in a backwards compatible way. :-) Would like to hear your thoughts.

Error: Cannot find module 'semver'

I'm getting this error trying to run mock-knex

        var knex = require('knex');
        var mockDB = require('mock-knex');
        var db = knex({
            client: 'sqlite'
        });

        mockDb.mock(db, '[email protected]');

Error: Cannot find module 'semver'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (/Projects/server/node_modules/mock-knex/index.js:6:14)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)

How to parse query columns in tracker insert

Hello, I'm wondering how you can parse the field names (columns) for an insert? Here is roughly what I'm trying to accomplish:

let usersDb = [];

describe('user', () => {
  before(() => {
    tracker.install();

    tracker.on('query', query => {
      let actions = {
        select: () => query.response(usersDb),
        insert: () => {
          usersDb.push(query.bindings);
          query.response(1);
        },
        update: () => {
          usersDb[0] = query.bindings;
          query.response(1);
        }
      };

      actions[query.method]();

      console.log('FULL USERS DB', query);
    });
  });

  // ...tests here...
});

Here's my console.log'd query object with random data:

{ method: 'insert',
  options: {},
  bindings:
   [ Wed Mar 23 2016 16:36:37 GMT-0400 (EDT),
     '[email protected]',
     '42aac085-a447-457d-8a96-012da279e84b',
     '$2a$10$FEDcFA4RzzsDU/F/4pHK.Oll4qBlnilK.4YpUlhY08at86j0sL3ze',
     Wed Mar 23 2016 16:36:37 GMT-0400 (EDT),
     'mi24woj19h' ],
  sql: 'insert into "users" ("created_at", "email", "id", "password", "updated_at", "username") values (?, ?, ?, ?, ?, ?) returning "id"',
  returning: 'id',
  response: [Function: response],
  result: [] }

As I understand it, bindings is an array and query.response expects an array of objects with keys being the column name. Is there an easier way to get the inserted column names other than manually parsing query.sql?

What I'm building is a full-loop integration test that creates a user, logs in with the user and deletes the user, so it'd be nice for the mock to maintain some state to simulate a real database.

Cannot find module 'knex/package' from 'index.js'

Hi there,

Thanks for the awesome package! Unfortunately I can't seem to get it to work. I'm using jest@^20.0.0, knex@^0.13.0 and mock-knex@^0.3.9 and typescript@^2.3.3:

Jest test case
import * as Knex from "knex";
import * as MockKnex from "mock-knex";

import RedshiftAdapter from "../../src/adapters/RedshiftAdapter";

import BaseQuery from "../../src/queries/BaseQuery";

class MockQuery extends BaseQuery {

  constructor(params) {
    super(params);
  }

  public execute = (client) => {

    return client("logs").select("*").limit(5);
  }
}

describe("RedshiftAdapter", () => {

  let adapter: RedshiftAdapter;
  let client: MockKnex;
  let tracker;

  beforeAll(() => {

    client = Knex({
      acquireConnectionTimeout: 2000,
      client: "pg",
      connection: {
        host     : "host",
        password : "password",
        port     : 1000,
        user     : "user",
        database : "database",
        ssl      : true,
      },
      debug: true,
    });

    MockKnex.mock(client);
    tracker = MockKnex.getTracker();
    adapter = new RedshiftAdapter(client);
  });

  beforeEach(() => {
    tracker.install();
  });

  afterAll(() => {
    MockKnex.unmock(client);
  });

  afterEach(() => {
    tracker.uninstall();
  });

  it("can make a request to Redshift", () => {

    tracker.on("query", (query) => {
      expect(query.method).toEqual("select");
      query.response([
        {
          action : "get",
          resource : "Apps",
        },
        {
          action : "get",
          resource : "Users",
        },
        {
          action : "get",
          resource : "AppUsers",
        },
      ]);
    });

    return adapter.execute(new MockQuery({}))
      .then((result) => {

        console.log(result);
      });
  });
});

Working with relationships

I'm currently working on building some tests around relationships of Bookshelf models. I have been using mock-knex but I'm not sure if it supports testing relationships. If this is possible, I'm having difficulty figuring out how.

Do I just add the "relations" field to my query response and try and guess what Bookshelf is expecting back?

Fix unmock()

unmock() is broken. It does not revert to a normal database connection.

It looks like there is already a branch underway to fix this behavior. I just wanted to call it out as an issue since I'm pretty interested in its resolution.

Mocking fails for [email protected]

Hi,

New version 0.17 has been released by knex and isn't part of the whitelisted plateform versions.

Getting this error on tests

    Unable to locate version: 0.17.0-next3

.forge().save() not triggering query event

knex: 0.11.10
mock-knex: 0.3.2
node: 4.4.7

.save() works when I'm not mocking, but when i'm mocking a .forge().save() never emits a query event

user.forge({
  personId: personId,
  email: email,
  password: crypt.encrypt(password),
  formioUserId: formioUserId
})
.save();
tracker.install();
tracker.on('query', (query) => {
  console.log('** NEVER LOGGED **');
  if (query.method === 'insert') {
    query.response([{
      personId: '',
      email: '',
      password: '',
      formioUserId: ''
    }]);
  }
});
Unhandled rejection TypeError: Cannot read property '0' of undefined
    at null.<anonymous> (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/lib/model.js:1015:57)
    at bound (domain.js:287:14)
    at runBound (domain.js:300:12)
    at tryCatcher (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/promise.js:507:31)
    at Promise._settlePromiseAt (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/promise.js:581:18)
    at Async._drainQueue (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:128:12)
    at Async._drainQueues (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (/Users/rocky.assad/code/serv/forms-service/node_modules/bookshelf/node_modules/bluebird/js/main/async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.