I'll try to approach this question with a little bit of abstraction, since going into the code details would be useless.
I have an angular module that is split in 2 source files, say source1.js
and source2.js
. Then i have 3 unit test files which are designed to test 3 angular service/factory/provider.
The project layout is as follows:
root
|
-dist
|
-source.min.js
-src
|
-source1.js
-source2.js
-tests
|
-unit
|
-service1.js
-service2.js
-service3.js
All the tests, run with karma and jasmine, pass and work as expected. See this bit of karma config to get the point:
files: [
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/*.js',
'tests/unit/*.js'
],
Next i minified source1 and source2 with gulpjs
into source.min.js
and tried to run tests using the minified file, so i changed the karma config as follows:
files: [
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'dist/*.js', // <--- see here.
'tests/unit/*.js'
],
With this configuration all tests are failing because of angular dependency injection - looks like the provider is not being resolved.
What could cause this? I mean, the source code should be the same.
This is a known problem with angular, dependency injection and minification. Also, the problem resides precisely in the details of the code.
Case 1:
Without explicit injection, angular tries to infer the service from the service name when using declared functions as controllers.
angular.module('app').controller('MyController', MyController);
function MyController(service1, service2, ...){ ... service1.doSomething ...}
Case 2:
With explicit injection, angular uses the controller function parameters in the order in which they were injected.
angular.module('app').controller('MyController', MyController);
MyController.$inject = ['service1', 'service2', ...]
function MyController(a, b, ...){ ... a.doSomething ... }
Case 1 will fail to work every time with minification because the name of the service will change and angular will not be able to infer the service that a, or b or c refer to by just looking at their names.
However, Case 2 will work every time because angular does not have to guess as it is being told by $inject that service1 is a and service 2 is b and so on.
If you are using a build utility like Gulp you can use ng-annotate which will automatically inject the dependencies for you in Case 1 and your code should still work.
In my own opinion and as a matter of style you should use case 2. I tend to follow something close to John Papa's Angular Style Guide
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.