Ho la seguente classe di coda di consumatori, che corre in modo ricorsivo attraverso promesse:numero Assert di chiamate ricorsive in Sinon
"use strict";
var queue = require("./queue"),
helpers = require("./helpers"),
vendors = require("../config/vendors"),
queueConf = require("../config/queue");
function Consumer() {
this.queue = new queue.TaskQueue();
this.currentItem = null;
this.port = null;
this.payload = null;
}
Consumer.prototype.payloadSuccessCb = function (data) {
this.payload = data;
this.run();
};
Consumer.prototype.failureCb = function (data) {
console.error(data);
throw new Error(data);
//TODO: Continue queue processing despite the error
};
Consumer.prototype.processItem = function (data) {
this.currentItem = data;
process.send("Proccess " + process.pid + " is processing item " + this.currentItem);
helpers.getPayload(this.currentItem).then(this.payloadSuccessCb, this.failureCb);
};
Consumer.prototype.wait = function() {
var self = this;
process.send("Proccess " + process.pid + " is waiting for new items");
setTimeout(function() {
self.run();
}, queueConf.waitTime);
};
Consumer.prototype.queueSuccessFb = function (data) {
console.error("here");
if (data) {
this.processItem(data);
} else {
this.wait();
}
};
Consumer.prototype.run = function() {
//this.port = helpers.getVendorPortById(this.currentItem);
this.queue.pop().then(this.queueSuccessFb, this.failureCb);
};
exports.Consumer = Consumer;
ho definito un test che sarà essenzialmente affermare che il flusso di lavoro corretto che sta accadendo, e che il consumatore in ultima analisi, gestisce tutte le attività in coda (si tratta di un test di integrazione che lavora di fronte a un vero e proprio mediatore Redis)
prova:
"use strict";
var consumer = require("./../../src/consumer"),
queue = require("./../../src/queue"),
Q = require("Q"),
sinon = require("sinon"),
assert = require("assert"),
queueConf = require("./../../config/queue"),
NUM_OF_ITEMS = 5,
queueInstance,
spy,
consumerInstance;
describe("consumer", function() {
beforeEach(function() {
queueInstance = new queue.TaskQueue();
});
describe("waiting for tasks while the queue is empty", function() {
describe("queue success call back", function() {
before(function() {
consumerInstance = new consumer.Consumer();
spy = sinon.spy(consumerInstance, "queueSuccessFb");
});
it("should call the success callback once per the defined period", function (done) {
consumerInstance.run();
setTimeout(function() {
sinon.assert.calledOnce(spy);
done();
}, queueConf.waitTime);
});
it("should call the success callback twice per the defined period + 1", function (done) {
consumerInstance.run();
setTimeout(function() {
sinon.assert.calledTwice(spy);
done();
}, queueConf.waitTime * 2);
});
});
describe("wait function", function() {
before(function() {
consumerInstance = new consumer.Consumer();
spy = sinon.spy(consumerInstance, "wait");
});
});
});
describe("task handling", function() {
beforeEach(function (done) {
this.timeout(6000);
var i, promises = [];
queueInstance = new queue.TaskQueue();
for (i = 1; i <= NUM_OF_ITEMS; i += 1) {
promises.push(queueInstance.push(i));
}
Q.all(promises).then(function() {
done();
});
});
afterEach(function() {
queueInstance.empty();
});
describe("sucess callback", function() {
before(function() {
consumerInstance = new consumer.Consumer();
spy = sinon.spy(consumerInstance, "queueSuccessFb");
});
it("should run all of the available tasks one by one", function (done) {
this.timeout(6000);
consumerInstance.run();
setTimeout(function() {
console.info(spy.callCount);
assert(spy.callCount === NUM_OF_ITEMS);
done();
}, 2000);
});
});
});
});
mio il problema è che il conteggio delle chiamate è sempre uguale a 1. Inizialmente pensavo che fosse necessaria una chiamata al metodo andCallThrough()
, simile a come funziona in Jasmine, ma poi ho scoperto che la funzione effettiva è stata invocata.
Provato usando sinon.useFakeTimers()
ma che non ha funzionato affatto (il test non sembrava attendere, il timeout nella classe consumer non stava sparando);
Comportamento prevista: callCount
è come NUM_OF_ITEMS
(tramite chiamate ricorsive). Comportamento effettivo: callCount
è sempre 1.