Search code examples
javascriptunit-testingsinonstubstubbing

stubbing redis publish method using sinon?


How can I stub the redis publish method?

// module ipc
const redis = require('redis');

module.exports = class IPC {
    constructor() {
        this.pub = redis.createClient();
    }

    publish(data) {
        this.pub.publish('hello', JSON.stringify(data));
    }
}

and another module

// module service
module.exports = class Service {
    constructor(ipc) {
        this.ipc = ipc;
    }

    sendData() {
        this.ipc.publish({ data: 'hello' })
    }
}

How could I stub the private variable pub in IPC class? I could stub the redis.createClient by using proxyquire, if I do that it will complain publish undefined

My current test code

    let ipcStub;
    before(() => {
        ipcStub = proxyquire('../ipc', {
            redis: {
                createClient: sinon.stub(redis, 'createClient'),
            }
        })
    });

    it('should return true', () => {
        const ipc = new ipcStub();

        const ipcPublishSpy = sinon.spy(ipc, 'publish')

        const service = new Service(ipc);

        service.sendData();

        assert.strictEqual(true, ipcPublishSpy.calledOnce);
    })

Solution

  • I found a way to do it just by using sinon

    Just need to create a stub instance using sinon.createStubInstance, then this stub will have all the functionalities from sinon without the implementation of the object (only the class method name)

    let ipcStub;
    before(() => {
        ipcStub = sinon.createStubInstance(IPC)
    });
    
    it('should return true', () => {
        const ipc = new ipcStub();
        const service = new Service(ipc);
    
        service.sendData();
    
        assert.strictEqual(true, ipc.publishSystem.calledOnce);
    })