Angular mocks .module() and .inject() interaction changed in 1.3.0 #9758
Description
In angular 1.2.x, any dependencies you mocked out using $provide were only mocked out when accessed from the module under test, but when mocks.inject was called, any injected dependencies were still built using the real implementations of their subdependencies.
In 1.3.0, once the module has mocked out the dependency, this mock is then substituted when required to construct injected dependencies in an inject call.
For example, take the following test setup:
var mockWindow, compile;
beforeEach(function () {
mockWindow = {
addEventListener:mockFunction(),
removeEventListener:mockFunction()
};
mocks.module('rcom.columnEditor', function($provide){
$provide.value('$window', mockWindow);
});
mocks.inject(function ($document, $rootScope, $compile) {
compile = $compile;
});
});
In angular 1.2.x this was fine, because, although $compile eventually depends on $window to give it a document object, it used the 'real' window, which gave it a real document.
In angular 1.3.0, this does not work, because mockWindow is used when $window is required by $document, and mockWindow does not define a document object. Therefore $document is an empty jqLite object which causes errors in $sce.
Is this a deliberate change? I can kinda see the logic to both ways but the 1.2.x method seems more practically useful. I can see lots of weird and difficult to track down issues being caused by the 1.3.0 behaviour and very little practical use for injecting objects built on mocks (if you need mock behaviour in a dependency, surely just mock it out at the top level object using $provide and not inject it at all?)
Thanks for any clarification!