Struggling to unit test a Ionic controller

I followed this post ( to create a simple unit test using Karma & Jasmine for a Ionic controller, but i keep getting undefined errors while the stated objects have been defined. I’m i missing something obvious? By the way, i’m able to run referenced tests from the blog above successfully which makes me think i’m missing something in mine.

Errors are as follows:

  1. TypeError: undefined is not an object (evaluating ‘authMock.login’) in /Users/projects/app/tests/unit-tests/login.controller.tests.js (line 65)
  2. TypeError: undefined is not an object (evaluating ‘deferredLogin.resolve’) in /Users/projects/app/tests/unit-tests/login.controller.tests.js (line 71)
  3. TypeError: undefined is not an object (evaluating ‘deferredLogin.reject’) in /Users/projects/app/tests/unit-tests/login.controller.tests.js (line 79)

Here’s the controller:

    angular.module('app').controller('LoginCtrl', function($scope, $state, $ionicPopup, $auth) {
  $scope.loginData = {};
  $scope.user = {
      email: '',
      password: ''

    $scope.doLogin = function(data) {
      $auth.login(data).then(function(authenticated) {
        $state.go('app.tabs.customer', {}, {reload: true});
      }, function(err) {
        var alertPopup = $ionicPopup.alert({
          title: 'Login failed!',
          template: 'Please check your credentials!'


Here’s the test:

    describe('LoginCtrl', function() {

    var controller,

    // load the module for our app

    // disable template caching
    beforeEach(angular.mock.module(function($provide, $urlRouterProvider) {
        $provide.value('$ionicTemplateCache', function(){} );

    // instantiate the controller and mocks for every test
    beforeEach(angular.mock.inject(function($controller, $q, $rootScope) {
        deferredLogin = $q.defer();

    $scope = $rootScope.$new();

        // mock dinnerService
        authMock = {
            login: jasmine.createSpy('login spy')

        // mock $state
        stateMock = jasmine.createSpyObj('$state spy', ['go']);

        // mock $ionicPopup
        ionicPopupMock = jasmine.createSpyObj('$ionicPopup spy', ['alert']);

        // instantiate LoginController
        controller = $controller('LoginCtrl', {
            '$scope': $scope,
            '$state': stateMock,
            '$ionicPopup': ionicPopupMock,
                        '$auth': authMock


    describe('#doLogin', function() {

        // call doLogin on the controller for every test
        beforeEach(inject(function(_$rootScope_) {

            $rootScope = _$rootScope_;

            var user = {
                email: '',
                password: 'test'



        it('should call login on $auth Service', function() {


        describe('when the login is executed,', function() {
            it('if successful, should change state to app.tabs.customer', function() {



            it('if unsuccessful, should show a popup', function() {



Here’s my Karma config:

    files: [
1 Like

Any ideas from the knowledgeable?

Hey EricK,

I’m encountering pretty much the exact same problem. Did you ever figure this out?

For ionic 2 this is a good start

Thanks so much for the tutorial link, EricK! Can’t wait to dive into that one. I did end up figuring out the error I was getting w/my Ionic 1 project - I was injecting a provider improperly. :slight_smile:

Try the following:

   deferredPopup = $q.defer();
    // mock $ionicPopup
    ionicPopupMock = jasmine.createSpyObj('$ionicPopup spy', ['alert']);

    ionicPopupMock.alert = jasmine.createSpy('alert')