1
votes

I'm trying to write unit tests for an angular service with jasmine/karma. I have a similar service test, which works just fine. But this one has some additional dependencies, is in a different module and just doesn't find the service with the inject.

The service looks something like this. bService is in the same module, but commonFactory and commonService are in another module, say commonModule.

(function () {
    'use strict';
     angular
         .module('myService')
         .service('aService', aService);

     aService.$inject = [
         'commonFactory',
         'commonService'
         'bService'
     ];

     function aService (
         commonFactory,
         commonService,
         bService
     ) {

     };

     return {
         codeIWantToTest: CodeIWantToTest;
     }

     function CodeIWantToTest () {
          console.log('surprise!');
     }
})();

My jasmine test looks like:

describe('myService.aService', function () {
    'use strict';
    var aService;
    // I tried adding beforeEach(module('commonModule')); too, but that didn't do anything
    beforeEach(module('myService'));

    beforeEach(function() {
        inject(function(_aService_) {
            console.log('getting aService');
            aService = _aService_;
        });
    }); 

    it('tests my service is defined', function() {
        expect(myService).toBeDefined();
    });
});

This test fails. myService isn't defined and the console.log in the inject function doesn't ever fire. My karma.conf.js basically lists the dependencies in the order that they're injected into the service, then adds the service then the test.

What would cause the inject to not grab the service? What am I missing? I mentioned I have a similar test for commonService and it works just fine. So I'm baffled.

1
You don't typically test services but the result of the service in a controller.Matthew Green
Edited code, added missing ' on bService. In case it wasn't an issue just from copying to SO.ste2425
it's missing the _ at the end of aService =_aService_ too.shelbydz
@MatthewGreen You don't typically test them like this? Does that mean it just won't work? I need to do it at a higher level?shelbydz
@MatthewGreen Where did you get this from? Actually it is the opposite; in unit tests you test separate units in isolation, so there are fewer moving parts and red test unambiguously indicates which unit was failed. Hence the name, unit test.Estus Flask

1 Answers

2
votes

Another dev on my team found the solution and I wanted to post it as an answer for the future people. I had a feeling it was a dependency problem, and it was. While we were loading all of the JS stuff correctly, the template that the component uses was loading another js dependency. So to fix this for jasmine, we had two different solutions:

at the top of the component test file, we could add:

beforeEach(function () {
    module(function ($provide) {
        $provide.constant('myMissingDependency', {
            // do things to load the dependency here
            });
    });
});

In our case it was a translation library

The other solution was to add a 'shim' file into the unit test directory and load it with karma.config.js ahead of the tests. That looked like:

(function() {
    angular
        .module('MyService')
        .constant('myMissingDependency', Object.freeze({
            // things to load the dependency
        }));
})();

I wasn't able to switch to Chrome because we're using Docker and I couldn't get the tests to run locally to run Chrome. So adding a second set of eyes to this was what I needed.