Estoy escribiendo casos de prueba de unidad para el siguiente archivo
//filename: a.js var amqp = require("amqplib"); class RMQ { constructor(connectionURI) { this.URI = connectionURI; } async getInstance() { var connection = await amqp.connect(this.URI); this.connection = connection; return connection; } } const RMQ_INSTANCE = new RMQ(process.env.RMQ_URL); module.exports = { RMQ_INSTANCE, }; Estoy usando la instancia RMQ_INSTANCE en el archivo a continuación
// filename: b.js const { RMQ_INSTANCE } = require("./a"); module.exports.publishEmail = async function(message) { var connection = await RMQ_INSTANCE.getInstance(); var channel = await connection.createChannel(); var exchange = "some_exchange"; var key = "some_key"; var msg = JSON.stringify(message); await channel.assertExchange(exchange, "topic", { durable: false }); await channel.publish(exchange, key, Buffer.from(msg)); setTimeout(function () { connection.close(); }, 500); } Estoy usando proxyrequire para RMQ_INSTANCE en b.js
// filename: b.test.js var proxyrequire = require("proxyquire").noCallThru(); var sinon = require("sinon"); const { assert } = require("sinon"); class fakeRMQClass { constructor(connectionURI) { this.URI = connectionURI; } async getInstance() { var connection = getFakeRMQStub() return connection; } } var producerTest = function () { it("producer connection - success test", async function () { var fakeRMQInstance = new fakeRMQClass("fake_url"); var rmqUtils = proxyrequire("../path/to/b.js", { "./a": fakeRMQInstance }); await rmqUtils.publishEmail("fake_msg"); }); afterEach(function () { sinon.verifyAndRestore(); }); }; describe("test_producer", producerTest);Pero veo que la burla no funciona correctamente. ¿Alguien podría ayudarme a simular esto correctamente?
Dado que RMQ_INSTANCE es un objeto, puede agregar sus métodos usando sinon.stub(obj, 'method') , no necesita usar el paquete proxyquire .
Dado que desea probar el módulo b , el módulo b solo se preocupa por la interfaz de RMQ_INSTANCE de la que depende, y la implementación específica no importa.
b.js :
const { RMQ_INSTANCE } = require('./a'); module.exports.publishEmail = async function (message) { var connection = await RMQ_INSTANCE.getInstance(); var channel = await connection.createChannel(); var exchange = 'some_exchange'; var key = 'some_key'; var msg = JSON.stringify(message); await channel.assertExchange(exchange, 'topic', { durable: false }); await channel.publish(exchange, key, Buffer.from(msg)); setTimeout(function () { connection.close(); }, 500); }; a.js :
class RMQ { constructor(connectionURI) { this.URI = connectionURI; } async getInstance() {} } const RMQ_INSTANCE = new RMQ(process.env.RMQ_URL); module.exports = { RMQ_INSTANCE }; b.test.js :
const sinon = require('sinon'); const { RMQ_INSTANCE } = require('./a'); const { publishEmail } = require('./b'); describe('test_producer', () => { let clock; before(() => { clock = sinon.useFakeTimers(); }); after(() => { clock.restore(); }); it('producer connection - success test', async () => { const channelStub = { assertExchange: sinon.stub().returnsThis(), publish: sinon.stub(), }; const connectionStub = { createChannel: sinon.stub().resolves(channelStub), close: sinon.stub() }; sinon.stub(RMQ_INSTANCE, 'getInstance').resolves(connectionStub); await publishEmail('fake message'); sinon.assert.calledOnce(RMQ_INSTANCE.getInstance); sinon.assert.calledOnce(connectionStub.createChannel); sinon.assert.calledWithExactly(channelStub.assertExchange, 'some_exchange', 'topic', { durable: false }); sinon.assert.calledWithExactly( channelStub.publish, 'some_exchange', 'some_key', Buffer.from(JSON.stringify('fake message')), ); clock.tick(500); sinon.assert.calledOnce(connectionStub.close); }); });resultado de la prueba:
test_producer ✓ producer connection - success test 1 passing (10ms) ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 75 | 100 | a.js | 100 | 100 | 50 | 100 | b.js | 100 | 100 | 100 | 100 | ----------|---------|----------|---------|---------|-------------------