Mocha and Chai test fails when testing function wi

2020-07-22 17:34发布

问题:

I'm new to TDD and working with Mocha and Chai. I have created a test that passes when a value is increased, but when that increase is put within a setInterval, it fails. The objective of this code is to have something move across the screen.

function startMovingThing(){
    var position = setInterval(function() {
        moveThing(10);
    }, 100);
}

function moveThing(number){
    thing.position += number;
    thingOnScreen.style.left = thing.position + 'px';
}

test:

describe('Thing', function() {

    it('should increase position', function(){
        assert.increases(startMovingThing, thing, 'position');
    });

});

How can I get this test (or what should the test be) to pass?

I don't want moveThing() to be outside of the interval, because if the interval is cleared and the function is called, the thing should not move.

回答1:

Ok, the problem is that you're using setInterval which is async and you're trying to assert that the value was changed in a synchronous way.

Here's a modified version of your test, using sinonjs to simulate that the time passed.

var assert = require('chai').assert;
var sinon = require('sinon');

var thing = { position: 0 }
var thingOnScreen = { style: { left: '' } };

function startMovingThing(){
    var position = setInterval(function() {
        moveThing(10);
    }, 100);
}

function moveThing(number){
    thing.position += number;
    thingOnScreen.style.left = thing.position + 'px';
}

describe('Thing', function() {

  beforeEach(function() {
    this.clock = sinon.useFakeTimers();
  });

  afterEach(function() {
    this.clock = sinon.restore();
  });

  it('should increase position', function(){
    startMovingThing();
    this.clock.tick(101);
    assert.equal(thing.position, 10);
  });
});

In summary, sinonjs is replacing the global functionality of setInterval and is executing the code without having to wait for the specified milliseconds.