0

As I try to follow the TDD way of development, I still struggle to find out how one can mock certain stuff in JavaScript. I am used to mocking in Java with Mockito and Spring (e.g. inject a mongo mock instead of a real mongo instance), but how do I approach this in JavaScript?

Let me make a simple example node.js with node-restify:

var mongoskin = require('mongoskin');
var restify = require('restify');

// ###############################
// ## Global Configuration
// ###############################

var mongoURL = process.env.MONGOHQ_URL || "mongodb://localhost/test";
var serverPort = process.env.PORT || 5000;

// ###############################
// ## Basic Setup
// ###############################
var server = restify.createServer({
    name: 'test'
});

server.use(connect.logger());
server.use(restify.acceptParser(server.acceptable));
server.use(restify.bodyParser());

var db = mongoskin.db(mongoURL);

// ###############################
// ## API
// ###############################

server.get('/api/v1/projects', function (req, res, next) {
    db.collection('projects').find().toArray(function (error, projects) {
        if (error) {
            return next(new restify.InternalError());
        }

        res.json(200, projects);

        return next();
    });
});

server.get('/api/v1/projects/:projectId', function (req, res, next) {
    if (req.params.projectId === null) {
        return next(new restify.InvalidArgumentError('ProjectId must not be null or empty.'))
    }

    db.collection('projects').findById(req.params.projectId, function (error, project) {
        if (error) {
            return next(new restify.InternalError());
        }

        res.json(200, project);

        return next();
    });
});

// ###############################
// ## Main Server Initialization
// ###############################

server.listen(serverPort, function () {
    console.log('%s listening at %s', server.name, server.url);
});

I would like to have now a test javascript file, where I can test those two 'get' methods. Furthermore I would like to mock the mongoskin instance ('db') so that I can use for example JSMockito to spy and pretend some behaviour.

What is now the best approach to this? Can someone post a small example file? And how do I manage to inject the mocked db instance?

Thanks for your help!

Thierry

rit
  • 2,308
  • 3
  • 19
  • 27

1 Answers1

0

Plenty of precedence out there for easily mocking a rest api in general: https://github.com/flatiron/nock

The problem with mocking a database is that its usually got an extremely complex and hairy api. There are two easy (and thus less correct in strict unit testing sense) ways to do this.

One is to have 'models' which wrap your entity access instead of going direct to the database driver. Then you can easily mock your model apis. This is fine, but a little annoying if you're just doing some basic database operations and you don't have a need for a big model abstraction.

The second is to just spin up a database with some test data and hook up to it during the test. This is a bit of a 'functional test' but also in my experience a lot more practical.

Josh
  • 12,602
  • 2
  • 41
  • 47