The Bndr
The Bndr

Reputation: 13394

Testing controllers with services

I'm new to angular and unit-testing.

I have an application module MyApp including basic things an services, that are needed in all other modules, like service for logging loggingService

I also have an module for handling everything about map&geo-positon, called MapModule and I have an main module for application logic, called MainModule

The MainModule contains a controller, that I like to test: messageSendCtrl The controller has some dependencies, like services from MapModule.

And: MainModule and MapModule has dependencies to the MyApp, because the loggingServiceis needed everywhere.

The code looks like that (pseudo-code):

MyApp

var MyApp = angular
        .module('MyApp', ['ngRoute','MainModule','MapModule']);

MyApp.service('loggingService', function (one, two) {
   [..] /*logging data somewhere for debugging application*/
});

MainModule

var MainModule = angular
        .module('MainModule', []); 
MainModule.controller('messageSendCtrl', 
    function($scope,$http, $location, locationService, loggingService) {
[...]
});

MapModule

var MapModule = angular
        .module('MapModule', ['uiGmapgoogle-maps']);
MapModule.service('locationService', function (loggingService) {
[...]

What I like to test is the messageSendCtrl from the MainModule. (probably) I was able to inject the location service into the test environment. But injecting the locationService was not successful.

Probably because locationService also uses the loggingService.

Running the test results in

Error: [$injector:unpr] Unknown provider: loggingServiceProvider <- loggingService <- locationService

My test looks like that:

describe('saving a document', function() {

  beforeEach(module('MainModule'));
  beforeEach(module('MyApp'));
  beforeEach(module('MapModule'));

  describe ('messageSendCtrl', function () {
    var scope,ctrl,locationService,loggingService; 

    beforeEach(inject(function($rootScope, $controller,_locationService_,_loggingService_) {
        scope = $rootScope.$new();
        ctrl = $controller('messageSendCtrl', 
                    {$scope: scope,
                     locationService: _locationService_,
                     loggingService : _loggingService_ });
    }));


      it('should actual not saved', function(){
        expect(scope.result).to.equal('unsaved');
    }); 
  })
});

So who can I solve the dependencies? Or is there an design problem at my application?

Upvotes: 0

Views: 81

Answers (1)

Ins
Ins

Reputation: 808

there are multiple things going on, let's check it one by one:

  1. at your test, you don't need do load all your modules, load just that module, that you want to test, your ctrl is in your MainModule, so use just beforeEach(module('MainModule'));
  2. every module should declare its dependencies, so your MainModule declaration should look like this: var MainModule = angular.module('MainModule', ['MyApp']); because one of your controller in your MainModule dependent on a service that is in an other module (MyApp)
  3. it is easier to test if one module do just one thing, so if you have a logging service, make a logging service module for that, and include that module where you want to use logging. So don't make modules that is responsible for several different things, because if an other module need logging, that module will get every other service that your "godmodule" contains, and that makes difficult to test, and find bugs.

Upvotes: 1

Related Questions