Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking database in node.js?

How would I mock out the database in my node.js application, which in this case uses mongodb as the backend for a blog REST API ?

Sure, I could set the database to a specific testing -database, but I would still save data and not test my code only, but also the database, so I am actually not doing unit testing but integration testing.
So what should one do? Create database wrappers as a middle layer between application and db and replace the DAL when in testing?

// app.js   var express = require('express');     app = express(),     mongo = require('mongoskin'),     db = mongo.db('localhost:27017/test?auto_reconnect');  app.get('/posts/:slug', function(req, res){     db.collection('posts').findOne({slug: req.params.slug}, function (err, post) {         res.send(JSON.stringify(post), 200);     }); });  app.listen(3000); 

// test.js r = require('requestah')(3000); describe("Does some testing", function() {    it("Fetches a blogpost by slug", function(done) {     r.get("/posts/aslug", function(res) {       expect(res.statusCode).to.equal(200);       expect(JSON.parse(res.body)["title"]).to.not.equal(null);       return done();     });    }); )); 
like image 913
Industrial Avatar asked Sep 21 '12 07:09

Industrial


2 Answers

I don't think database related code can be properly tested without testing it with the database software. That's because the code you're testing is not just javascript but also the database query string. Even though in your case the queries look simple you can't rely on it being that way forever.

So any database emulation layer will necessarily implement the entire database (minus disk storage perhaps). By then you end up doing integration testing with the database emulator even though you call it unit testing. Another downside is that the database emulator may end up having a different set of bugs compared to the database and you may end up having to code for both the database emulator and the database (kind of like the situation with IE vs Firefox vs Chrome etc.).

Therefore, in my opinion, the only way to correctly test your code is to interface it with the real database.

like image 170
slebetman Avatar answered Sep 25 '22 12:09

slebetman


There is a general rule of thumb when it comes to mocking which is

Don't mock anything you don't own.

If you want to mock out the database hide it behind an abstracted service layer and mock that layer. Then make sure you integration test the actual service layer.

Personally I've gone away from using mocks for testing and use them for top-to-bottom design helping me drive development from the top towards the bottom mocking out service layers as I go and then eventually implementing those layers and writing integration tests. Used as a test tool they tend to make your test very brittle and in the worst case leads to a divergence between actual behavior and mocked behavior.

like image 39
christkv Avatar answered Sep 22 '22 12:09

christkv