Reputation: 356
Using spyOn on an object seems to fail if the method is called in a callback function. Any calls to the method in a callback won't be noticed by jasmine.
Please see the code below, I've created a spy on child.print() method. If I call child.print() in a callback (setTimeout), it doesn't work:
it('test', function() {
const child = {
print: function() {
console.log('child');
}
};
spyOn(child, 'print');
const parent = {
callChildInCallback: function() {
setTimeout(()=> child.print(), 1000);
}
};
parent.callChildInCallback();
expect(child.print.calls.count()).toEqual(1);
});
This one will failed with error "Expected 0 to equal 1."
However if I call it directly, it works:
it('test', function() {
const child = {
print: function() {
console.log('child');
}
};
spyOn(child, 'print');
const parent = {
callChild: function() {
child.print();
}
};
parent.callChild();
expect(child.print.calls.count()).toEqual(1);
});
I tried to set a breakpoint into the callback, and it seems the spy wrap around the function we're testing is gone, and that's the reason on the surface. Can someone explain why this happen, and the proper way to do it?
Thanks for reading~
Upvotes: 2
Views: 1235
Reputation: 2695
You'll need to use jasmine clock to work with timeout functions
it('test', function() {
jasmine.clock().install();
const child = {
print: function() {
console.log('child');
}
};
spyOn(child, 'print').and.callThrough();
const parent = {
callChildInCallback: function() {
setTimeout(function() {
child.print()
}, 1000);
}
};
parent.callChildInCallback();
jasmine.clock().tick(1001);
expect(child.print.calls.count()).toEqual(1);
});
Upvotes: 3