Question

Say I have this function:

function doSomething(n) {
    for (var i = 0; i < n; i++) {
        doSomethingElse();
    }
}

How would I test if the doSomethingElse function is called n times??

I tried something like:

test("Testing something", function () {
    var spy = sinon.spy(doSomethingElse);

    doSomething(12);

    equal(spy.callCount, 12, "doSomethingElse is called 12 times");
});

but this does not seem to work, because you have to call the spy while the doSomething() calls the original doSomethingElse(). How can I make this work with QUnit/sinon.js?

EDIT

Maybe it isn't even a good idea? Does this fall outside the 'unit testing' because another function is called?

Was it helpful?

Solution

You could do something like this:

test('example1', function () {
    var originalDoSomethingElse = doSomethingElse;
    doSomethingElse = sinon.spy(doSomethingElse);
    doSomething(12);
    strictEqual(doSomethingElse.callCount, 12);
    doSomethingElse = originalDoSomethingElse;
});

For example: JSFiddle.

OTHER TIPS

function doSomething(n) {
    for (var i = 0; i < n; i++) {
        doSomethingElse();
    }
}

you cant spy on doSomethingElse.

doSomethingElse is not testable ,when something is not testable it needs to be refactored.

You either need to inject doSomethingElse in doSomething

OR

use a pointer:

pointer={doSomethingElse:function(){}};

function doSomething(n) {
    for (var i = 0; i < n; i++) {
        pointer.doSomethingElse();
    }
}

Declare a global variable named count and assign it 0

window.count = 0;

Now, inside the doSomethingElse() function, increment it like count++

So, whenever you access count variable, it will return the number of times the doSomethingElse() is called.

Full code might be:

window.count = 0;

function doSomething(n) {
    for (var i = 0; i < n; i++) {
        doSomethingElse();
    }
}

function doSomethingElse() {
    count++;
    // do something here
}

doSomething(22);
alert(count);// alerts 22

Or even better, call count++ whenever the function you want to be tested is called in code.

Demo: http://jsfiddle.net/583ZJ/

Note: If you want to remove it, then just remove the variable declaration (window.count=0;) and count++

function debugCalls(f) {
    if (!f.count) 
        f.count = 0;

    f.count++;
}

function doSomethingElse()
{
    debugCalls(arguments.callee);


    // function code...
}


// usage
for(var i = 0; i < 100; i++) doSomethingElse();

alert(doSomethingElse.count);

this way it makes it easier for you to debug any function you want just by inserting debugCalls(arguments.callee) inside the function you want to save the number of times it has been called.

In Node.js 14.2.0 one can use the new currently experimental CallTracker API to do the job without using Sinon or another additional library.

var assert = require('assert');

test("Testing something", function () {
    var originalDoSomethingElse = doSomethingElse;
    var tracker = new assert.CallTracker();
    doSomethingElse = tracker.calls(doSomethingElse, 12);
    try {
        doSomething(12);
        tracker.verify();
    } finally {
        doSomethingElse = originalDoSomethingElse;
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top