3
\$\begingroup\$

As a development team we've recently started to transition from MVC to Angular. None of us have had prior experience with it so a lot of creating the new client was very much trial and error. I've been put in charge of sorting out unit tests however I'm finding it very difficult to unit test.

In my experience if something is difficult to unit test it generally means some refactoring is in order. Problem is I do not have enough experience with Angular to say yay or nay on this.

Main angular module:

angular.module('serviceApp', ['mgcrea.ngStrap', 'ngRoute', 'LocalStorageModule', 'account.module', 'admin.module', 'design-code-review.module', 'early-load-test.module', 'integration-load-test.module', 'production-validation.module', 'risk-modelling.module', 'unit-test-profiling.module','error.module'])
.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
        .when('/login', {
            templateUrl: '/views/account/login.html',
            controller: 'account.controller'
        })
         .when('/admin', {
             templateUrl: '/views/admin/project-admin.html',
             controller: 'admin.controller'
         })
        .when('/register', {
            templateUrl: '/views/account/register.html',
            controller: 'account.controller'
        })
        .otherwise('/login');
}])    
.config(function($httpProvider){
    $httpProvider.interceptors.push('authentication.interceptor')
})
.run(['authentication.service', function (authentication) {
    authentication.populateAuthentication();
}]);

Declared in other js files are factories and services for our serviceApp

Example factory class:

angular.module('serviceApp')
.factory('storage.factory', ['$http', 'applicationSettings', 'localStorageService', function ($http, applicationSettings, localStorageService) {

    var getItems = function () {
        return $http.get(applicationSettings.apiLocation + 'Items/GetAll').then(function (response) {
            localStorageService.set('items', response.data);
        },
        function (error) {
            console.log("Could not retrieve data.");
        });
    };

    return {
        getItems: getItems 
    };
}]);

Currently I'm having a lot of trouble trying to test these factories and services because of the sheer number of dependencies that serviceApp has. When looking for examples online I see that a lot of modules have only 1 or 2 dependencies which got me thinking whether the above is typical of an Angular application. Is having a lot of dependencies for a module like this ok in Angular? Or am I being a bit dense and need to get my unit testing in order?

\$\endgroup\$
7
  • \$\begingroup\$ There is not a lot of code here to review, and we are expected to extrapolate a bit from the little code that you have posted. Furthermore, you haven't shown us your unit tests. It feels a bit like a general design question, perhaps suited for Software Engineering or Software Quality Assurance & Testing. \$\endgroup\$ – 200_success Jan 25 '17 at 12:56
  • \$\begingroup\$ The review is aimed entirely at my angular.module posted first, with the factory being provided as some insight only. The unit tests for this module are not the subject for review (hence why they are not posted) \$\endgroup\$ – Novastorm Jan 25 '17 at 13:36
  • \$\begingroup\$ The first snippet looks like any old generic Angular app. So the question is basically about whether it is normal to have so many dependent modules? \$\endgroup\$ – 200_success Jan 25 '17 at 13:39
  • \$\begingroup\$ This is actual code from our application; indeed that and if not what could be done to improve it. It was a toss up between posting it here or Software Engineering but I felt it's place would be more here, though I can appreciate it falls into a slightly grey area between the two \$\endgroup\$ – Novastorm Jan 25 '17 at 13:48
  • \$\begingroup\$ If you wish to keep this question here on Code Review, then at least change the title to state the purpose of the code under review, rather than your concern about it, as required by the site standards stated in How to Ask. Also, add the javascript language tag. \$\endgroup\$ – 200_success Jan 25 '17 at 13:50
1
\$\begingroup\$

Injecting the $injector service can help by facilitating the use of optional dependencies:

app.factory('templateRepository', [ '$injector', function($injector) {
  function lookupUrlFor(contentType) {
   // Do your translation here
  }

  return {
    getTemplate: function(contentType) {
      var templateCache = $injector.get('$templateCache');
      return templateCache.get(lookupUrlFor(contentType));
      }
    }
}])

That way the unit tests only needs to inject $injector and mocks can be avoided.

References

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.