Currently running Angular 1.2.x with karma-mocha 0.2.0 and karma-chai 0.1.0.
The following is my attempt to write some simple Unit Tests for my MentorAvailabilityDashboardCtrl
which is based off the Mentors
module. Everything passes when individually run, but when I run the test as is I get an error stating "Error: [ng:areq] Argument 'MentorAvailabilityDashboardCtrl' is not a function, got undefined"
It makes me think that Mocha or the AngularMock gets reset after the test get run once and is undefined after.
Test running all at once
Testing running all at once (commenting other test out)
Why is my controller going undefined after the first test run and Is there anything I can do have it persist for each test run?
'use strict';
/* globals gon: false */
import angular from 'angular';
describe('MentorAvailabilityDashboardCtrl', function() {
let createController, $scope;
beforeEach(function() {
angular.module('Mentors', []);
require('./mentor_availability_dashboard')
angular.mock.module('Mentors');
});
beforeEach(angular.mock.inject(function ($rootScope, $controller) {
function MockMentorProfile() {}
function MockFlash() {}
$scope = $rootScope.$new()
createController = $controller('MentorAvailabilityDashboardCtrl', {
$scope: $scope,
MentorProfile: MockMentorProfile,
Flash: MockFlash
});
}));
describe('validation checks', function() {
it('should invalidate form fields on initialization', function() {
expect($scope.validatedFields()).to.eq(false);
});
it('should validate specifc field on initialization', function() {
$scope.courseFilter = 'Rails';
expect($scope.fieldValidated($scope.courseFilter)).to.eq(true);
});
it('should validate form fields on completion', function() {
$scope.courseFilter = 'Rails';
$scope.osFilter = 'Windows';
$scope.studentFilter = { student: 'Billy' };
$scope.paceFilter = '12 weeks';
$scope.startFilter = { monday: 'Monday' };
expect($scope.validatedFields()).to.eq(true);
});
it('should be able to click form with clearForm()', function() {
$scope.courseFilter = 'Rails';
$scope.clearForm()
expect($scope.courseFilter).to.eq('');
});
});
});
PhantomJS 1.9.8 (Mac OS X 0.0.0) MentorAvailabilityDashboardCtrl "before each" hook: workFn for "should validate specifc field on initialization" FAILED
Error: [ng:areq] Argument 'MentorAvailabilityDashboardCtrl' is not a function, got undefined
http://errors.angularjs.org/1.2.26/ng/areq?p0=MentorAvailabilityDashboardCtrl&p1=not%20a%20function%2C%20got%20undefined
at assertArg (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:1509)
at assertArgFn (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:1520)
at /Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:7278
at /Users/bdoug/Bloc/frontend/test/tests_index.js:15072 <- webpack:///frontend/legacy_org/mentors/mentor_availability_dashboard.test.js:23:8
at invoke (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:3966)
at workFn (/Users/bdoug/Bloc/vendor/assets/bower_components/angular-mocks/angular-mocks.js:2161)
It seems like you are requiring the controller definition in a beforeEach block and that might have something to do with it. Probably a scoping issue. You might try avoiding angular mocks alltogether and just test the controller function directly. Since you are using es6 modules you can export the controller function directly as a named export.
export function MyController($scope, Flash) {
//...
}
MyController.$inject = ['$scope', 'Flash'];
angular.module('Mentors').controller('MyController')
Then in the test
import sinon from 'sinon';
import {MyController} from './my_controller'
it('...', function() {
let scope = {};
let Flash = sinon.mock();
MyController(scope, Flash);
//... assertions
})