Alxs Alxs - 4 months ago 47
Javascript Question

Karma - Unknown provider error: menuFactoryProvider <- menuFactory

When trying to test my controller, Karma fails with a string of errors all beginning with:


Karma - Error: [$injector:unpr] Unknown provider: menuFactoryProvider
<- menuFactory


It seems menuFactory (which is actually a service now) isn't properly injected, but I can't figure out why. Karma output shown here for clarity:

enter image description here

Here's my menucontroller-test.js:

describe('Controller: MenuController', function () {

// load the controller's module
beforeEach(module('confusionApp'));

var MenuController, scope, $httpBackend;

});

// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, _$httpBackend_, $rootScope, menuFactory) {

// place here mocked dependencies
$httpBackend = _$httpBackend_;

$httpBackend.expectGET("http://localhost:3000/dishes").respond([
{
"id": 0,
...
},
{
"id": 1,
...
}
]);

scope = $rootScope.$new();
MenuController = $controller('MenuController', {
$scope: scope, menuFactory: menuFactory
});
$httpBackend.flush();

}));

it('should have showDetails as false', function () {

expect(scope.showDetails).toBeFalsy();

});
...
});


Excerpt from controllers.js

'use strict';

angular.module('confusionApp')

.controller('MenuController', ['$scope', 'menuFactory', function($scope, menuFactory) {

$scope.tab = 1;
$scope.filtText = '';
$scope.showDetails = false;
$scope.showMenu = false;
$scope.message = "Loading ...";

menuFactory.getDishes().query(
function(response) {
$scope.dishes = response;
$scope.showMenu = true;
},
function(response) {
$scope.message = "Error: "+response.status + " " + response.statusText;
});


Excerpt from services.js (note again menuFactory is actually a service, not a factory)

'use strict';

angular.module('confusionApp')
.constant("baseURL", "http://localhost:3000/")
.service('menuFactory', ['$resource', 'baseURL', function($resource, baseURL) {

var promotions = [
{
_id:0,
name:'Weekend Grand Buffet',
image: 'images/buffet.png',
label:'New',
price:'19.99',
description:'Featuring mouthwatering combinations with a choice of five different salads, six enticing appetizers, six main entrees and five choicest desserts. Free flowing bubbly and soft drinks. All for just $19.99 per person ',
}

];

this.getDishes = function(){
return $resource(baseURL+"dishes/:id",null, {'update':{method:'PUT' }});
};

// implement a function named getPromotion
// that returns a selected promotion.
this.getPromotion = function(index) {
return promotions[index];
};


}])

Answer

you had accidentally closed the describe method after injecting module that's why it couldn't inject your service. It works now!

describe('Controller: MenuController', function () {

      // load the controller's module
      beforeEach(module('confusionApp'));

      var MenuController, scope, $httpBackend,menuFactory;       

      // Initialize the controller and a mock scope
      beforeEach(inject(function ($injector,$controller, _$httpBackend_,  $rootScope, _menuFactory_) {

              // place here mocked dependencies
          $httpBackend = _$httpBackend_; 
          menuFactory = $injector.get('menuFactory');                 
          $httpBackend.expectGET("http://localhost:3000/dishes").respond([
            {
          "id": 0,
          ...
          },
          {
          "id": 1,
          ...
          }
          ]);

        scope = $rootScope.$new();
        MenuController = $controller('MenuController', {
          $scope: scope, menuFactory: menuFactory
        });
                $httpBackend.flush();

      }));

        it('should have showDetails as false', function () {

        expect(scope.showDetails).toBeFalsy();

      });
      ...
      });
 });