@EricK wrote:
I followed this post (http://gonehybrid.com/how-to-write-automated-tests-for-your-ionic-app-part-2/) 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:
- TypeError: undefined is not an object (evaluating 'authMock.login') in /Users/projects/app/tests/unit-tests/login.controller.tests.js (line 65)
- TypeError: undefined is not an object (evaluating 'deferredLogin.resolve') in /Users/projects/app/tests/unit-tests/login.controller.tests.js (line 71)
- 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, deferredLogin, $scope, authMock, stateMock, ionicPopupMock; // load the module for our app beforeEach(angular.mock.module('app')); // disable template caching beforeEach(angular.mock.module(function($provide, $urlRouterProvider) { $provide.value('$ionicTemplateCache', function(){} ); $urlRouterProvider.deferIntercept(); })); // 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') .and.returnValue(deferredLogin.promise) }; // 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: 'test@yahoo.com', password: 'test' }; $scope.doLogin(user); })); it('should call login on $auth Service', function() { expect(authMock.login).toHaveBeenCalledWith(user); }); describe('when the login is executed,', function() { it('if successful, should change state to app.tabs.customer', function() { deferredLogin.resolve(); $rootScope.$digest(); expect(stateMock.go).toHaveBeenCalledWith('app.tabs.customer'); }); it('if unsuccessful, should show a popup', function() { deferredLogin.reject(); $rootScope.$digest(); expect(ionicPopupMock.alert).toHaveBeenCalled(); }); }); }) });
Here's my Karma config:
files: [ '../www/lib/ionic/js/ionic.bundle.js', '../www/lib/angular-mocks/angular-mocks.js', '../www/js/*.js', '../www/js/**/*.js', 'unit-tests/**/*.js' ],
Posts: 1
Participants: 1