Skip to content Skip to sidebar Skip to footer

Stubbing Redis Interactions In Javascript Using Sinon

I am working in node.js. My app interacts with Redis via the node_redis module. I'm using mocha and sinon to automate testing of my app. My app looks something like this: ...snip

Solution 1:

What you could do is use something like Proxyquire or Rewire. I'll be using rewire for the example.

Your snippet of code you want to stub:

var redisClient = redis.createClient(redisPort, redisHost);
var someValue = redisClient.get("someKey");
return someValue;

Then in your test you can use rewire:

varRewire = require('rewire');

var myModule = Rewire("../your/module/to/test.js");

var redisMock = {
    get: sinon.spy(function(something){
             return"someValue";
         });
};

myModule.__set__('redisClient', redisMock);

This way you can have your redisClient replaced and you can check with the spy if the function was called.

Solution 2:

Few key points are:

  • Stub redisClient before loading main module.
  • Stub the CRUD methods for redisClient.

Below is my main module:

/* Main module */const redis = require('redis');
const redisClient = redis.createClient();

functionvalue(){
  return redisClient.get('someKey');
}

module.exports = {value: value}

Below is my test script:

/* Test */var sinon = require('sinon');
var redis = require('redis');

// stub redis.createClientvar redisClient = {
    'get': () =>"someValue"
}

var redisGetSpy = sinon.spy(redisClient, "get");
var redisClientStub = sinon.stub(redis,
                                 "createClient").callsFake(() => redisClient);

// require main modulevar main = require('./main.js');

console.log(main.value(),
            redisClientStub.called,
            redisGetSpy.called, 
            redisGetSpy.callCount);

Solution 3:

You can also use something like redis-mock which is a drop in replacement for node_redis that runs in memory.

Use rewire (or Jest module mocks or whatever) to load the mock client in your tests instead of the real client and run all your tests against the in-memory version.

Solution 4:

The other way is to do in your class static function getRedis and mock it. For example:

let redis = {
   createClient: function() {},
};
let connection = {
   saddAsync: function() {},
   spopAsync: function() {},
};
let saddStub = sinon.stub(connection, 'saddAsync');
sinon.stub(redis, 'createClient').returns(connection);
sinon.stub(Redis, 'getRedis').returns(redis);

expect(saddStub).to.be.calledOnce;

Inside your class connect function looks like:

this.connection = YourClass.getRedis().createClient(port, host, optional);

Solution 5:

This initially seemed very trivial to me, but I was faced with a lot of caveats, particularly because I was using jest for testing, which does not supports proxyquire. My objective was to mock the request dependency of redis, so here's how I achieved it:

// The objective is to mock this dependencyconst redis = require('redis');

const redisClient = redis.createClient();
redis.set('key','value');

Mocking dependency with rewiremock:

const rewiremock = require('rewiremock/node');

const app = rewiremock.proxy('./app', {
  redis: {
    createClient() { 
      console.log('mocking createClient');
    },
    set() {
      console.log('mocking set');
    }
  },
});

The catch is that you can't use rewire, or proxyquire with jest, that you need a library like rewiremock to mock this dependency.

REPL example

Post a Comment for "Stubbing Redis Interactions In Javascript Using Sinon"