Search code examples
javascriptjqueryqunit

QUnit - test in loop, index always the same


I am trying to test some code and for that I need to make some tests in loop, like this:

for (var i = 1; i <= 5; i++) {
    QUnit.test('Hello ' + i, (assert) => {
        console.log(i);
        assert.ok( 1 == '1', 'Result: ' + i);
    });
}

Click here for working example at jsFiddle

But for some reason i in the loop (and result) is always 6, so this code gives me output like this:

6
6
6
6
6

What am I doing wrong?


Solution

  • Given that QUnit defines all tests prior to running them, you're a victim of the classic problem of var scope - vars are bound to the function, not to the for loop.

    What this means is:
    You define your test with a given value for i, but this value will have changed when the test is actually running.

    You have a few ways around this:

    Create an IIFE and define your test inside it

    for (var i = 1; i <= 5; i++) {
        (function (j) {
            QUnit.test('Hello ' + j, (assert) => {
                console.log(j);
                assert.ok( 1 == '1', 'Result: ' + j);
            });
        })(i);
    }
    

    Why this works: the j variable above will be bound to the scope of that IIFE. Its value will not change when the test is run.

    Use let keyword in an ES6 environment

    for (let i = 1; i <= 5; i++) {
        QUnit.test('Hello ' + i, (assert) => {
            console.log(i);
            assert.ok( 1 == '1', 'Result: ' + i);
        });
    }
    

    Why this works: ES6 finally introduces block scoping, but this is done via the keywords let or const.

    some parts of this answer corroborated from here