3

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?

5 Answers 5

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanx you did (unlike the other answers) understand they are qunit tests. I am going to try this!
0
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();
    }
}

Comments

0

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++

3 Comments

this called refactoring but the worst way.
I only want the count number when running the test suites, not when running the original code..
@user3153169 then you need to refactor your code anyway,you cant spy on a closure.unless you inject doSomethingElse() somewhere somehow.
0
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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.