Reputation: 3447
I am setting up tests for my application, and I wish to check a method was called x times using Sinon, my testing framework is Mocha.
How can I achieve this, below is the code I wish to test, I'm looking to ensure recursiveRequest is called x times by createClients.
Nodezilla.prototype.createClients = function(batched, i){
var self = this;
if(batched)
batchRequests();
if(batched == false && i < this.virtualUsers){
// set timeout to help prevent out of memory errors
setTimeout( function() {
self.createClients(false, i+1);
}, 0 );
}else{
this.recursiveRequest();
}
};
Nodezilla.prototype.recursiveRequest = function(){
var self = this;
self.hrtime = process.hrtime();
if(!this.halt){
self.reqMade++;
this.http.get(this.options, function(resp){
resp.on('data', function(){})
.on("end", function(){
self.onSuccess();
});
}).on("error", function(e){
self.onError();
});
}
};
Attempted test but no avail as callCount returns 0.
var assert = require('assert'),
sinon = require('sinon'),
nz = require('../Nodezilla'),
nt = new nz("localhost", 10);
describe('Nodezilla', function(){
describe('createClients', function(){
before(function() {
sinon.spy(nt, "recursiveRequest");
});
it('should call recursiveRequest() 10 times', function(){
nt.createClients(false, 0);
assert(nt.recursiveRequest.callCount);
});
});
});
Upvotes: 3
Views: 5461
Reputation: 6200
createClients seems to be an async request, without a callback/promise. This means your test is evaluated immediately, and does not wait for results. I'd suggest to re-write the function with a callback or promise so you are able to act on the event of processing completed, and then this should work:
var assert = require('assert'),
sinon = require('sinon'),
nz = require('../Nodezilla'),
nt = new nz("localhost", 1);
describe('Nodezilla', function () {
describe('createClients', function () {
it('should call recursiveRequest() 10 times', function (itCallback) {
// Moved into the test:
sinon.spy(nt, "recursiveRequest");
nt.createClients(false, 0, function(){
// Needs to wait for action to actually be called:
assert(nt.recursiveRequest.callCount == 10);
// Now that the test is actually finished, end it:
itCallback();
});
});
});
});
Skipping the before statement, as this might interfere with scopes, sinon.spy being synchronous can be called inside the test.
Also note I have introduced a callback in this statement:
it('should call recursiveRequest() 10 times', function (callback) {
to hold the test from finishing before the inner callback is called.
Edit:
As for adding the callbacks, I'm not sure what does batchRequests()
does, but go like that:
Nodezilla.prototype.createClients = function (batched, i, cb) {
var self = this;
if (batched)
batchRequests();
if (batched == false && i < this.virtualUsers) {
// set timeout to help prevent out of memory errors
setTimeout(function () {
self.createClients(false, i + 1, cb);
}, 0);
} else {
this.recursiveRequest(cb);
}
};
And then:
Nodezilla.prototype.recursiveRequest = function (cb) {
var self = this;
self.hrtime = process.hrtime();
if (!this.halt) {
self.reqMade++;
this.http.get(this.options, function (resp) {
resp.on('data', function () {
})
.on("end", function () {
self.onSuccess();
cb();
});
}).on("error", function (e) {
self.onError();
cb();
});
} else {
// I assume you are doing nothing in this case, so just call the callback:
cb();
}
};
Also note you can use the callback for error handling.
Upvotes: 3