Reputation: 2722
I am trying to mock the $timeout service, which I know how to do, however, I need to be able to call the ORIGINAL $timeout service from within my mock. However, it just ends up with a stack overflow, recursively calling itself...
describe("myUnitTest", function () {
var $compile;
var $rootScope;
var $window;
var $timeout;
var timerTriggeredCount;
beforeEach(function () {
module("myModuleBeingTested", function ($provide) {
$provide.value("$timeout", fakeTimeout);
function fakeTimeout(func) {
timerTriggeredCount++;
return $timeout(func, 1, false); // need this to call the original $timeout service
}
fakeTimeout.cancel = function(timer) {
$timeout.cancel(timer); // need this to call the original $timeout servic
}
});
inject(["$compile", "$rootScope", "$window", "$timeout", function (c, rs, w, t) {
$compile = c;
$rootScope = rs;
$window = w;
$timeout = t;
}]);
});
....
Upvotes: 2
Views: 81
Reputation: 2722
OK, I got it. I need to use a decorator (see here at the very end of the page):
describe("myUnitTest", function () {
var $compile;
var $rootScope;
var $window;
var $timeout;
var timerTriggeredCount;
beforeEach(function () {
module("myModuleBeingTested", function ($provide) {
var fakeTimeoutDecorator = [
"$delegate", function ($delegate) {
var oldTimeout = $delegate;
var fakeTimeout = function (fn, delay, invokeApply) {
return oldTimeout(function() {
timerTriggeredCount++;
fn();
}, 1, invokeApply);
};
for (var prop in oldTimeout) {
fakeTimeout[prop] = oldTimeout[prop];
}
return fakeTimeout;
}
];
$provide.decorator("$timeout", fakeTimeoutDecorator);
});
....
Upvotes: 2