I love using console log for feedback perhaps too much, and sometimes I run into code that as convention we've added $timeout in the directive/service/controller, sometimes as long as 500 ms, and now the problem is during unit test, I noticed only console.logs directly under the it constructor gets sent out to karma and output to the screen.
wrapped console logs under timeout or rather wrapped assertions under $timeout do not yield any result as if ignored, what's the solution to timeouts?
In your unit tests, you load ngMock
, which overwrites the orignal $timeout
with its mock. Mock $timeout
doesn't work like the real JavaScript timeout
. To get it to call the code that's inside it, you have to do $timeout.flush()
from your unit test.
If $timeout
worked like the real timeout
, you would've had to write asynchronous unit-tests for all functions that use $timeout
.
Here's an example of a simplified function that uses $timeout
and how I test it:
gaApi.getReport = function() {
report = $q.defer()
$timeout(function() {
$http({method: 'GET', url: 'https://www.googleapis.com/analytics/v3/data/ga'})
.success(function(body) {
report.resolve(body)
})
}, 300)
return report.promise
}
A unit test:
describe('getReport', function() {
it('should return report data from Google Analytics', function() {
gaApi.getReport().then(function(body) {
expect(body.kind).toBe('analytics#gaData')
})
$timeout.flush()
$httpBackend.flush()
})
})