user5506608
user5506608

Reputation:

inject a custom service in karma jasmine

I was trying out jasmine with karma. I have a custom service ApiService which i need to inject in my spec file. But when am trying to inject the ApiService i get Error: [$injector:unpr] Unknown provider: ApiService <- ApiService

this is my controller

'use strict';
angular.module('assessmentApp')
    .controller('NewUserController', NewUserController)
    .run(["$rootScope", "$anchorScroll", function($rootScope, $anchorScroll) {
        $rootScope.$on("$locationChangeSuccess", function() {
            $anchorScroll();
        });
    }]);

NewUserController.$inject = ['$scope', '$rootScope', '$location', '$timeout', 'ApiService'];

function NewUserController($scope, $rootScope, $location, $timeout, ApiService) {
    //console.log("innn   NewUserController2   ::::")
    var vm = this;
    var boardsClassSubjectCombinations = [];
    var studentId = $rootScope.globals.studentId;
    var assessmentCampaignId = $scope.assessmentCampaignId = $rootScope.globals.assessmentCampaignId;
    vm.currentQuestion = 1;

    //sanity check if the user already has academics added
    ApiService.getAll('students/' + studentId + '/latest-student-academic', true, ['students/{{id}}/academic'])
        .then(function(res) {
            if (res.data) {
                //send this guy to home page
                $location.url('/home');
            }
        });

    function getStates() {
        ApiService.getAll('states', true).then(function(response) {
            $scope.states = response.data;
        });
    }
    getStates();

}

this is my test file

describe('NewUserController Test', function() {
  beforeEach(module('assessmentApp'));
    // beforeEach(module('assets'));
    //beforeEach(module('ApiService'))


  var scope, location, timeout,apiService, q, authenticationService;

  beforeEach(inject(function($location,$rootScope,$timeout, ApiService){

    scope = $rootScope.$new();
    location = $location;

    timeout = $timeout;
    q = _$q_;
    console.log(ApiService)

    //spyOn(ApiService, 'ApiService');
    //spyOn(Point, 'method');

    // console.log("ApiService :::"+ApiService)

    //$controller = _$controller_('NewUserController', { $scope: $scope });
    //console.log("NewUserController======="+$controller)
  }));

  describe('$scope.grade', function() {
    it('sets the strength to "strong" if the password length is >8 chars', function() {
      console.log("$location ::::"+location)
      console.log("scope ::::"+scope)
      console.log("timeout ::::"+timeout)
      console.log("ApiService ::::"+ApiSrvce)
      console.log("q ::::"+q)
      //console.lopg("authenticationService :::"+authenticationService)
      //console.log("$scope ::::::"+$scope)
      expect(true).toEqual(true);
    });
  });
});

This is my karma.conf.js file

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
      //'test-main.js',
      '../bower_components/jquery/dist/jquery.js',
      '../bower_components/angular/angular.js',
      '../bower_components/bootstrap/dist/js/bootstrap.js',
      '../bower_components/angular-route/angular-route.js',
      '../bower_components/particles.js/particles.js',
      '../bower_components/angular-cookies/angular-cookies.js',
      '../bower_components/toastr/toastr.js',
      '../bower_components/angular-sanitize/angular-sanitize.js',
      '../bower_components/d3/d3.js',
      '../bower_components/c3/c3.js',
      '../bower_components/moment/moment.js',
      '../bower_components/humanize-duration/humanize-duration.js',
      '../bower_components/angular-timer/dist/angular-timer.js',
      '../bower_components/underscore/underscore.js',
      '../bower_components/scrollreveal/dist/scrollreveal.js',
      '../bower_components/lodash/lodash.js',
      '../bower_components/angular-youtube-mb/src/angular-youtube-embed.js',
      '../bower_components/angular-mocks/angular-mocks.js',
      //'../assets/**/*.js',
      //'../assets/**/*.html',
      //'../bower_components/angular/angular.js',
      //'../bower_components/angular-mocks/angular-mocks.js',
      '../app/scripts/app.js',
      '../app/scripts/controllers/**/*.js',
      '../app/scripts/directives/**/*.js',
      '../app/scripts/services/**/*.js',
      '../app/scripts/**/*.js',
      '../../assets/src/assets/services/*.js',
      'spec/**/*.js'      

    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

What i see is, when i try to inject any custom service it skips the beforeEach function and the logs i get in it function is

LOG: '$location ::::undefined'
LOG: 'scope ::::undefined'
LOG: 'timeout ::::undefined'
LOG: 'ApiService ::::undefined'

Upvotes: 0

Views: 1450

Answers (1)

rrd
rrd

Reputation: 5957

So I would suggest this kind of structure:

angular.mock.module(function($provide) {
  apiService = jasmine.createSpy('apiService', ['getAll']);
  $provide.value('apiService', apiService);

  // Mock out other services here in the same fashion;
});

inject(function(_$controller_, _$rootScope_) {
  $controller =
    _$controller_('NewUserController', { $scope: _$rootScope_.$new() });
});

Then in your tests, you would refer to the apiService like this. Ideally you would make an it() statement for each bit you want to test, like say, the return value of getState(), but we'll do it all in one here:

it ('calls getState()', function () {
  // Mock out what the apiService will do; you only care what comes back
  // so you can see what $scope.states looks like in the end;
  apiService.getAll.and.returnValue({ Promise.resolve({ foo: 1 }) });

  // Spy on the controller's own getState method;
  spyOn($controller, 'getState').and.callFake(() => true);

  // Store the return value of the getState call;
  expect($controller.getState).toHaveBeenCalled();

  // Overall the calls count for getAll on the apiService should be two;
  expect(apiService.getAll.calls.count()).toEqual(2);

  // getState() will have been called, and should return the object;
  expect($controller.states).toEqual({ foo: 1 });
});

Upvotes: 1

Related Questions