Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express JS Integration testing with Supertest and mock database

Is it possible to test an Express JS REST API using supertest but replacing the actual database connection with a mock database object? I have unit tests covering the database models and other parts of the application as well as functional tests of the API endpoints making actual database connections, but I have a weird requirement to create integration tests that are like the functional tests but use mock database connections. A sample endpoint controller is below:

  var model = require('../../../lib/models/list');

  module.exports = {
    index: function(req, res) {
      var data = { key: 'domains', table: 'demo.events'};

      var dataModel = new model(data);

      dataModel.query().then(function(results) {
        res.respond({data: results}, 200);
      }).fail(function(err) {
        console.log(err);
        res.respond({message: 'there was an error retrieving data'}, 500);
      });
    }
  };

And the index for the URI is

var express = require('express'), app, exports;
app = exports = module.exports = express();

exports.callbacks = require('./controller');

app.get('/', exports.callbacks.index);

The list model used in the controller connects to the database and retrieves the data that is output. The challenge is mocking that actual database call while still using supertest to make the request and retrieve the data from the URI

Any information would be helpful including if you think this is a bad or pointless idea

like image 277
Jazzuzz Avatar asked Oct 17 '13 21:10

Jazzuzz


People also ask

How do I test my Express API with SuperTest?

First, we add a new post to the database. Then, we make a PATCH request to the update post endpoint and send our post data. Once we got a response from the server, we can assert them and check if the data in the database is updated. Finally, let's add a test case for the delete post route.

What is SuperTest used for?

SuperTest is a Node. js library that helps developers test APIs. It extends another library called superagent, a JavaScript HTTP client for Node. js and the browser.

What is the difference between SuperTest and jest?

Jest provides us matchers like toBe and toContain that can be used to test that the responses have an exact value or contain a certain value respectively. Supertest includes the expect method that allows us test the statuscode of the response and the type of the response.

Can you use Jest for integration testing?

Now once you run npm run test , or jest , in the command line, it will create the test_book_database database, seed it with any migrations you had (to set up the schema and any necessary data), and you can access the database in each integration test.


1 Answers

I have had limited success with 2 approaches:

1) use rewire to replace the database driver library like mongodb with a mocked one, perhaps using the spy/stub/mock capabilities of sinon

2) Set your db as an app setting via app.set('mongodb', connectedDb) for dev/prod but in test environment set a mock database instead. This requires your db-accessing code (models typically) to get the DB from the app, or otherwise be mock-friendly or designed with a dependency injection pattern.

Neither of these make everything clean and painless, but I have gotten some utility out of them.

like image 100
Peter Lyons Avatar answered Oct 03 '22 03:10

Peter Lyons