So, I fight this day all the time. After reading this post, I also felt that there was something with the answer, it turns out. None of the above answers provide a clear explanation of where and why to use $rootScope.$digest . So this is what I came up with.
First, why? You must use $rootScope.$digest whenever you respond to a non-w500> event or callback. This will include pure DOM events, jQuery events, and other third-party Promise libraries other than $q , which are part of angular.
Secondly, where? In your code, not your test. There is no need to inject $rootScope into your test, it is only necessary in your actual angular service. That's where all of the above does not give a clear answer to the question, they show that $rootScope.$digest is called from the test.
I hope this helps the next person who comes for a long time, this is the same problem.
Update
I deleted this post yesterday when it was voted. Today I continued this problem trying to use the answers kindly provided above. So, I am waiting for my answer at the cost of reputation points, and therefore I cancel it.
This is what you need in event handlers that are not angular, and you are using $ q and trying to test Jasmine.
something.on('ready', function(err) { $rootScope.$apply(function(){deferred.resolve()}); });
Note that in some cases it may have to be wrapped in $ timeout.
something.on('ready', function(err) { $timeout(function(){ $rootScope.$apply(function(){deferred.resolve()}); }); });
One more note. In the original problem examples, you call done at the wrong time. You must call done inside the then (either catch or finally ) promise method after it is resolved. You invoke it before the promise is resolved, which leads to the completion of the it clause.