使用 sinon 存根 redis 发布方法?

stubbing redis publish method using sinon?

如何存根 redis 发布方法?

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

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

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

和另一个模块

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

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

如何在 IPC class 中存入私有变量 pub? 我可以使用 proxyquire 存根 redis.createClient,如果我这样做,它会抱怨 publish undefined

我目前的测试代码

    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);
    })

你只需要在 publish 方法上设置间谍,不需要 proxyquire.
例如

import {expect} from 'chai';
import sinon from 'sinon';

class IPC {
    constructor() {
        this.pub = {
            publish:() => {} //here your redis requirement
        };
    }

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

class Service {
    constructor(ipc) {
        this.ipc = ipc;
    }

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

describe('Test Service', () => {
    it('should call publish ', () => {
        const ipc = new IPC;
        sinon.spy(ipc.pub,'publish');
        const service = new Service(ipc);

        service.sendData();

        expect(ipc.pub.publish.calledOnce).to.be.true;
    });
});

我找到了一种方法,只需使用 sinon

只需要使用sinon.createStubInstance创建存根实例, 那么这个存根将具有 sinon 中的所有功能,而无需实现对象(仅 class 方法名称)

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);
})