I have code that is something like this:
function doThing() {
if (invalidInput) {
console.error(\'Invalid input.\');
return;
}
$timeout(function()
No uncertainty is welcome in unit tests, it should be predictable whether there is something to flush for $timeout
or not.
In this piece of code two cases should be tested, in both $timeout
shouldn't be a blackbox, it should be a stub instead (optionally a spy that wraps around the real service).
beforeEach(module('app', ($provide) => {
$provide.decorator('$timeout', ($delegate) => {
var timeoutSpy = jasmine.createSpy().and.returnValue($delegate);
// methods aren't copied automatically to spy
return angular.extend(timeoutSpy, $delegate);
});
}));
The first is falsey invalidInput
:
...
MyService.doThing();
expect($timeout).not.toHaveBeenCalled();
And the second one is truthy invalidInput
:
...
MyService.doThing();
expect($timeout).toHaveBeenCalledWith(jasmine.any(Function), 1000);
$timeout.flush();
expect(MyService.doThing).toHaveBeenCalledTimes(2);
Disregarding this case, it is generally a good thing to return promises from promise-powered functions:
function doThing() {
if (invalidInput) {
console.error('Invalid input.');
return;
}
return $timeout(function() {
return MyService.doThing();
}, 1000);
}
This way the callers (most likely specs) may have some control on function's asynchronous behaviour.
Answering the question directly, the expected way to do 'flushIfFlushable()' is
try {
$timeout.verifyNoPendingTasks(); // just for semantics, not really necessary
$timeout.flush();
} catch (e) {}
Which should be avoided for the reasons listed above.