Reputation: 436
How can I test a property inside a timeout from another called method?
I want to test a property if it's changed inside the setTimeout
but using sinons useFakeTimer
doesn't seems to work. Or am I missing something?
To illustrate here's my code
const fs = require('fs');
function Afunc (context) {
this.test = context;
}
module.exports = Afunc;
Afunc.prototype.start = function () {
const self = this;
this.readFile(function (error, content) {
setTimeout(function () {
self.test = 'changed';
self.start();
}, 1000);
});
}
Afunc.prototype.readFile = function (callback) {
fs.readFile('./file', function (error, content) {
if (error) {
return callback(error);
}
callback(null, content);
})
}
And here's what I have so far.
describe('Afunc', function () {
let sandbox, clock, afunc;
before(function () {
sandbox = sinon.createSandbox();
});
beforeEach(function () {
clock = sinon.useFakeTimers();
afunc = new Afunc('test');
sandbox.stub(afunc, 'readFile').yieldsAsync(null);
});
afterEach(function () {
clock.restore();
sandbox.restore();
});
it('should change test to `changed`', function () {
afunc.start();
clock.tick(1000);
afunc.test.should.be.equal('changed');
});
});
after the clock.tick
check the property test is not changed.
Any help is deeply appreciated! Thanks in advance.
Upvotes: 1
Views: 226
Reputation: 45810
Just change this:
sandbox.stub(afunc, 'readFile').yieldsAsync(null);
...to this:
sandbox.stub(afunc, 'readFile').yields();
...and it should work.
Details
yieldsAsync
defers using process.nextTick
so the callback passed to readFile
wasn't getting called until "all instructions in the current call stack are processed"...which in this case was your test function.
So the callback that changed afunc.test
to 'changed'
was getting called...but not until after your test completed.
Upvotes: 1