5

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?

gustavohenke
  • 40,997
  • 14
  • 121
  • 129
SmxCde
  • 5,053
  • 7
  • 25
  • 45

1 Answers1

4

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

Community
  • 1
  • 1
gustavohenke
  • 40,997
  • 14
  • 121
  • 129