Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mock a fake database for when unit testing against Knex?

I've been using Knex successfully to connect to a backend database. But I want to be able to unit test my code. Is there a way to mock the database connection?

I've tried using proxyquire but I can't seem to get it to work.

The problem seems to be with the way Knex is initialized.

var knex = require('knex')({
  client: 'mysql',
  connection: {}
});

I setup knex to be mocked in my unit test.

myService = proxyquire('../app/myService', {
        'knex': knexProxy
});

My service includes knex.

var knex = require('knex').knex,

When my service runs a query, it fails.

var sql = knex("table_name");
sql.insert(rowToInsert, "auto_increment_id");
sql.then(function (insertId) {
    resolve();
}, function (err) {
    reject(err);
});

For some reason I just can't seem to capture the request before it attempts the connection.

I've also, tried to create a custom Knex Client, but that hasn't worked yet either.

like image 308
Trevor Allred Avatar asked Jan 27 '15 07:01

Trevor Allred


People also ask

Can database be mocked for unit testing?

Unit tests are incredibly important to us as developers because they allow us to demonstrate the correctness of the code we've written. More importantly, unit tests allow us to make updates to our code base with confidence that we haven't broken anything.

Should you mock a database?

The best solution is to virtualise and parallelise your isolated integration tests against a well-known data set. It runs more slowly, but you'll spend much less time setting this up correctly, fixing bugs that are due to bad mocking or bad emulation. Conclusion: Stop mocking your database.

What is mocking a database?

What is Database Mocking? Database Mocking is a technique that allows you to set the desired database state (for different tables) in your tests to let specific data sets ready for future test execution.

Why do we mock the database?

Mocks help to emulate and examine outcoming interactions. These interactions are calls the system under test (SUT) makes to its dependencies to change their state. Stubs help to emulate incoming interactions. These interactions are calls the SUT makes to its dependencies to get input data.


1 Answers

Using jest:

Create the file /__mocks__/knex.js in your app root:

module.exports = () => ({
  select: jest.fn().mockReturnThis(),
  from: jest.fn().mockReturnThis(),
  where: jest.fn().mockReturnThis(),
  first: jest.fn().mockReturnThis(),
  then: jest.fn(function (done) {
    done(null)
  })
})

Pass the desired return value to done

like image 187
Eduardo Avatar answered Sep 21 '22 11:09

Eduardo