Andna
Andna

Reputation: 6689

nodejs - mocking modules, naive approach

Currently I am writing some unit tests for my server side code that is written using nodejs.

Now, I have a situation where my custom module is using some other modules, mine or from nodejs standard library and I wanted to mock them. Firstly I googled around for some existing solutions, for example I found: https://github.com/thlorenz/proxyquire and https://github.com/mfncooper/mockery.

But today I tried to use naive approach and do something like this: moduleUnderTest

var fs = require('fs');
exports.foo = function(){
  console.log("===foo===");
  fs.read();
}

and file moduleUnderTestSpec:

var fs = require('fs');
var moduleUnderTests = require('../server/moduleUnderTests.js');

fs.read = function(){
  console.log("===read===");
}

and when I run grunt jasmine_node I can see:

===foo===
===read===

so in this simple case I could swap one of the functions in fs module for other one. Is there any situations where my approach will not work?

Upvotes: 3

Views: 1135

Answers (2)

Bulkan
Bulkan

Reputation: 2592

First take a look at sinon as it will help you mock or stub out functions easily.

When you require a module in Node.js the modules are cached according to docs on modules.

The only problem I see with your solution is that later if you need to use the real fs.read you won't be able to as it's lost. For example you can use Sinon like so;

var fs = require('fs');
var sinon = require('sinon');

// mock fs.read
sinon
  .stub(fs, 'read')
  .returns("string data");

// test your code that uses fs.read
assert(fs.read.calledOnce);

// then restore
fs.read.restore();

Upvotes: 5

vkurchatkin
vkurchatkin

Reputation: 13570

Your approach is ok, but it will work only if module exports object. If a module exports function (which happens a lot) or anything else, you can't mock it. That is, you can mock only a property of module object, but not the whole object.

Upvotes: 2

Related Questions