Reputation: 906
I am using Oracle Database driver for Node.js node-oracledb. I did some research and not able to find any clear solution on how to unit test DB connection. Should I connect to the real database or mock the connection. Which framework will be good for mocking DB connection? I want to unit test post request /API/login which depend on oracledb. Sharing the code below. Please guide.
var express = require('express');
var router = express.Router();
var oracledb = require('oracledb');
var jwt = require('jsonwebtoken');
var database = {};
router.use('/', function postLogins(req, res) {
database.user = req.body.email.toUpperCase();
database.password = req.body.password;
database.connectString = process.env.DB_HOST;
oracledb.getConnection(
database,
function connectToDatabase(connectionError, connection) {
var payload;
if (connectionError) {
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: 'Error connecting to DB',
detailed_message: connectionError.message
}));
return;
}
payload = {
sub: req.body.email
};
res.status(200).json({
user: req.body.email,
token: jwt.sign(payload, process.env.SECRET_KEY, { expiresIn: '8h' })
});
connection.release(function onRelease(releaseError) {
if (releaseError) {
console.error(releaseError.message);
} else {
console.log('POST /logins : Connection released');
}
});
}
);
});
module.exports = router;
Upvotes: 0
Views: 3141
Reputation: 55972
Should I connect to the real database or mock the connection.
It really depends on the scope of your test. Oracle is a dependency that you don't control and must interact with. As long as this code is executed at some point it will be tested, maybe by a client, but hopefully before it reaches the client. I think that both approaches are valuable.
Which framework will be good for mocking DB connection?
I would try and use some sort of design patterns to isolate your dependencies and increase testability. The highly nested anonymous functions make it difficult to isolate parts of your code, almost requiring you to exercise your handler at a coarse level. There are a couple options that could help to break apart your handler and make it more testable at a unit level. I think the first step could be to extract your handler:
class PostLogins {
constructor(db) {
this.db = db || oracledb;
}
handle(req, res) {
// use this.db
}
}
var pl = new PostLogins();
router.use('/', pl.handle);
This will allow you to exercise your handler directly, but of course will not test that it is wired into your framework. It also allows you to provide a stub implementation of oracle for your unit test, to verify that the flow of your handler works correctly. Even with a unit test using a stub oracle you will be missing coverage on your actual oracle interactions, and your http interactions. Another refactor that would help with testability is to break out connectToDatabase
.
Depending on the maturity of your project it might make sense to first create a coarse-grained high level test that starts up oracle, starts up your webserver and then exercises your endpoint and verifies that the successful response has been received. I would opt for this approach if it is very early in your projects lifecycle and implementations are still changing OR if your project has already been release to clients, to allow you to change the implementations and refactor and still have test coverage that HTTP and successful requests haven't regressed.
Upvotes: 1