Repeated $document event handlers during unit tests #4996
Description
Problem
A number of ui-bootstrap's services register event handlers on places like document
when they are created. These are never removed, and so build up during unit tests, with a duplicate for every unit test that directly or indirectly injects the service.
Cause
Each test a new injector is created, which means that each test that uses one of the offending services creates a new version of the service. Thus each test registers a new version of the event handler but no test ever removes old ones.
Effect
This is not going to be a problem for most production environments unless angular apps are being destroyed and recreated, but it is definitely an issue for almost anyone running unit tests.
As a specific example, $uibModal
's document keydown handler keeps enough in its closure to hold onto $rootScope
and many of the other modal services. One set of this data is kept around for every test that $uibModal
is directly or indirectly injected into. This can cause large memory usage and slow downs after a number of tests.
I could also see these extra mistakely running handlers causing hard to track bugs that only occur in the tests, though I have not confirmed this.
Example
This plunker highlights the problem for $uibModal
, but it occurs elsewhere in the library too.
Fix
- Rely on something like this line in
ngMock
to wipe out events on$document
. Would need to add this code to any unit tests that even indirectly refer to ui-bootstrap services. - Allow cleanup on
$rootScope.$destroy()
. This isn't currently done by default inngMock
but seems like a good way to clean up. I've submitted a pull request to angular for this.
Not sure about good current solutions, so if anyone has ideas I'm happy to write a pull request.