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
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With