I can't make it work! I just looked all over the Internet, and I tried other solutions, but I can't make it work.
I got a filter, and I want to test with Karma and Jasmine. Here is my code:
app.js:
var services = angular.module('myApp.services', [ 'ngResource' ]);
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
filters.js
'use strict';
/* Filters */
angular.module('myApp.filters', [])
.filter(
'lowerAndCapital',
[ function() {
return function(text) {
if (text != undefined) {
var str = text.toLowerCase();
var arreglo = str.split(" ");
var result = "";
for (var i = 0; i < arreglo.length; i++) {
result += " "
+ arreglo[i].charAt(0).toUpperCase()
+ arreglo[i]
.substring(1, arreglo[i].length + 1);
}
return result;
}
}
}]);
filterSpecs.js
'use strict';
/* Jasmine specification for filters go here */
describe('filter', function() {
beforeEach(function () {
module('myApp.filters');
});
describe('lowerAndCapital', function() {
it('deberia de convertir le texto a minuscula y con letra capital',
inject(function(lowerAndCapital) {
expect(lowerAndCapital("john")).toEqual(
"John");
}));
});
});
karma.config.js
module.exports = function(config){
config.set({
basePath : '../',
files : [
'main/webapp/resources/scripts/angular/angular.js',
'main/webapp/resources/scripts/angular/angular-route.js',
'main/webapp/resources/scripts/angular/angular-mocks.js',
'main/webapp/resources/js/*.js',
'test/unit/*.js'
],
autoWatch : true,
frameworks: ['jasmine'],
browsers : ['Chrome'],
plugins : [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine',
'karma-junit-reporter'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});
};
And here is the error:
Chrome 36.0.1985 (Windows 7) filter lowerAndCapital deberia de convertir le text
o a minuscula y con letra capital FAILED
Error: [$injector:unpr] Unknown provider: lowerAndCapitalProvider <- low
erAndCapital
http://errors.angularjs.org/1.2.16/$injector/unpr?p0=lowerAndCapitalProv
ider%20%3C-%20lowerAndCapital
at E:/workspace/GPS/src/main/webapp/resources/scripts/angular/angula
r.js:78:12
at E:/workspace/GPS/src/main/webapp/resources/scripts/angular/angula
r.js:3705:19
at Object.getService [as get] (E:/workspace/GPS/src/main/webapp/reso
urces/scripts/angular/angular.js:3832:39)
at E:/workspace/GPS/src/main/webapp/resources/scripts/angular/angula
r.js:3710:45
at getService (E:/workspace/GPS/src/main/webapp/resources/scripts/an
gular/angular.js:3832:39)
at Object.invoke (E:/workspace/GPS/src/main/webapp/resources/scripts
/angular/angular.js:3859:13)
at workFn (E:/workspace/GPS/src/main/webapp/resources/scripts/angula
r/angular-mocks.js:2147:20)
Error: Declaration Location
at window.inject.angular.mock.inject (E:/workspace/GPS/src/main/weba
pp/resources/scripts/angular/angular-mocks.js:2132:25)
at null.<anonymous> (E:/workspace/GPS/src/test/unit/filtersSpec.js:1
5:5)
at null.<anonymous> (E:/workspace/GPS/src/test/unit/filtersSpec.js:1
2:2)
at E:/workspace/GPS/src/test/unit/filtersSpec.js:5:1
Chrome 36.0.1985 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.359 secs / 0.0
14 secs)
You should probably try inject filterprovider and get lowerAndCapital filter.
var $filter;
beforeEach(function () {
module('app');
});
beforeEach( inject(function (_$filter_) { //<-- Get the filter provider
$filter = _$filter_;
}));
it('deberia de convertir le texto a minuscula y con letra capital',function(){
expect($filter('lowerAndCapital')("john")).toEqual("John");
});
Plnkr
Or Postfix your filtername with "Filter" and use it
beforeEach( inject(function (_lowerAndCapitalFilter_) {
$filter = _lowerAndCapitalFilter_;
}));
Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To achieve this a filter definition consists of a factory function which is annotated with dependencies and is responsible for creating a filter function.
But there is a bug in your code because of split(" ") so you may want to trim the result returned.
Demo
Related
I'm trying to write unit tests for my new Angular App and have troubles. Below is my controller.
'use strict';
angular.module('nileLeApp')
.controller('RegisterController', function ($scope, $translate, $timeout, vcRecaptchaService, Auth, Country, Timezone, RecaptchaService) {
$scope.success = null;
$scope.error = null;
$scope.doNotMatch = null;
$scope.errorUserExists = null;
$scope.registerAccount = {};
$timeout(function () {
angular.element('[ng-model="registerAccount.email"]').focus();
});
$scope.loadCountries = function () {
Country.getCountries()
.then(function (result) {
$scope.countries = result.data;
});
};
$scope.loadTimezones = function () {
Timezone.getTimezones()
.then(function (result) {
$scope.timezones = result.data;
});
};
// ============ Recaptcha specific code START ===============
$scope.recaptcha = {};
$scope.recaptcha.recaptchaResponse = null;
$scope.recaptchaWidgetId = null;
$scope.setResponse = function (response) {
$scope.recaptcha.recaptchaResponse = response;
$scope.recaptchaMissing = false;
};
$scope.setWidgetId = function (widgetId) {
$scope.recaptchaWidgetId = widgetId;
};
$scope.cbExpiration = function () {
$scope.recaptcha.recaptchaResponse = null;
};
// ============ Recaptcha specific code END ===============
$scope.createAccount = function () {
Auth.createAccount($scope.registerAccount).then(function (response) {
$scope.success = true;
}).catch(function (response) {
$scope.success = false;
});
}
$scope.register = function () {
$scope.recaptchaMissing = false;
$scope.recaptchaInvalid = false;
if ($scope.recaptcha.recaptchaResponse != null) {
RecaptchaService.verify($scope.recaptcha).$promise
.then(function (response) {
if (response.data) {
$scope.createAccount();
} else {
$scope.recaptchaInvalid = true;
vcRecaptchaService.reload($scope.recaptchaWidgetId); // Reload captcha
}
}).catch(function (response) {
});
} else {
$scope.recaptchaMissing = true;
}
};
$scope.loadCountries();
$scope.loadTimezones();
});
Below is the test I'm trying.
'use strict';
describe('Register Controllers Tests', function () {
describe('RegisterController', function () {
// actual implementations
var $scope;
var $q;
// mocks
var MockTimeout;
var MockTranslate;
var MockAuth;
var MockCountry;
var MockTimezone;
// local utility function
var createController;
beforeEach(inject(function ($injector) {
$q = $injector.get('$q');
$scope = $injector.get('$rootScope').$new();
MockTimeout = jasmine.createSpy('MockTimeout');
MockAuth = jasmine.createSpyObj('MockAuth', ['createAccount']);
MockCountry = jasmine.createSpyObj('MockCountry', ['getCountries']);
MockTimezone = jasmine.createSpyObj('MockTimezone', ['getTimezones']);
MockTranslate = jasmine.createSpyObj('MockTranslate', ['use']);
var locals = {
'$scope': $scope,
'$translate': MockTranslate,
'$timeout': MockTimeout,
'Auth': MockAuth,
'Country': MockCountry,
'Timezone': MockTimezone
};
createController = function () {
$injector.get('$controller')('RegisterController', locals);
};
}));
it('should load countries on page load', function () {
var mockCountryResponse = [{
'countryId': 1,
'alpha2Code': "AF",
'countryName': "Afghanistan"
}];
MockCountry.getCountries.and.returnValue($q.resolve(mockCountryResponse));
MockTimezone.getTimezones.and.returnValue($q.resolve());
MockAuth.createAccount.and.returnValue($q.resolve());
// given
createController();
$scope.$apply($scope.loadCountries);
expect($scope.countries).toEqual(mockCountryResponse);
});
});
The above expectation doesn't work because $scope.countries is undefined. Following is the error message.
TypeError: 'undefined' is not an object (evaluating 'result.data')
Also, I see the test getting called twice for some strange reason. Below is my Karma configuration file.
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function (config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '../../',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
// bower:js
'main/webapp/bower_components/es5-shim/es5-shim.js',
'main/webapp/bower_components/jquery/dist/jquery.js',
'main/webapp/bower_components/angular/angular.js',
'main/webapp/bower_components/angular-animate/angular-animate.js',
'main/webapp/bower_components/angular-aria/angular-aria.js',
'main/webapp/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'main/webapp/bower_components/bootstrap/dist/js/bootstrap.js',
'main/webapp/bower_components/angular-bootstrap-nav-tree/dist/abn_tree_directive.js',
'main/webapp/bower_components/angular-file-upload/angular-file-upload.js',
'main/webapp/bower_components/angular-messages/angular-messages.js',
'main/webapp/bower_components/skycons/skycons.js',
'main/webapp/bower_components/angular-skycons/angular-skycons.js',
'main/webapp/bower_components/angular-smart-table/dist/smart-table.min.js',
'main/webapp/bower_components/angular-touch/angular-touch.js',
'main/webapp/bower_components/angular-cache-buster/angular-cache-buster.js',
'main/webapp/bower_components/angular-cookies/angular-cookies.js',
'main/webapp/bower_components/angular-dynamic-locale/src/tmhDynamicLocale.js',
'main/webapp/bower_components/angular-local-storage/dist/angular-local-storage.js',
'main/webapp/bower_components/angular-loading-bar/build/loading-bar.js',
'main/webapp/bower_components/angular-resource/angular-resource.js',
'main/webapp/bower_components/angular-sanitize/angular-sanitize.js',
'main/webapp/bower_components/angular-translate/angular-translate.js',
'main/webapp/bower_components/messageformat/messageformat.js',
'main/webapp/bower_components/angular-translate-interpolation-messageformat/angular-translate-interpolation-messageformat.js',
'main/webapp/bower_components/angular-translate-loader-partial/angular-translate-loader-partial.js',
'main/webapp/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'main/webapp/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.js',
'main/webapp/bower_components/angular-translate-storage-local/angular-translate-storage-local.js',
'main/webapp/bower_components/angular-ui-router/release/angular-ui-router.js',
'main/webapp/bower_components/moment/moment.js',
'main/webapp/bower_components/fullcalendar/dist/fullcalendar.js',
'main/webapp/bower_components/angular-ui-calendar/src/calendar.js',
'main/webapp/bower_components/angular-ui-grid/ui-grid.js',
'main/webapp/bower_components/angular-ui-select/dist/select.js',
'main/webapp/bower_components/angular-ui-utils/ui-utils.js',
'main/webapp/bower_components/angular-xeditable/dist/js/xeditable.js',
'main/webapp/bower_components/angularjs-toaster/toaster.js',
'main/webapp/bower_components/angular-strap/dist/angular-strap.js',
'main/webapp/bower_components/angular-strap/dist/angular-strap.tpl.js',
'main/webapp/bower_components/angular-recaptcha/release/angular-recaptcha.js',
'main/webapp/bower_components/bootstrap-daterangepicker/daterangepicker.js',
'main/webapp/bower_components/bootstrap-filestyle/src/bootstrap-filestyle.js',
'main/webapp/bower_components/bootstrap-slider/bootstrap-slider.js',
'main/webapp/bower_components/bootstrap-tagsinput/dist/bootstrap-tagsinput.js',
'main/webapp/bower_components/bootstrap-wysiwyg/bootstrap-wysiwyg.js',
'main/webapp/bower_components/bower-jvectormap/jquery-jvectormap-1.2.2.min.js',
'main/webapp/bower_components/datatables/media/js/jquery.dataTables.js',
'main/webapp/bower_components/flot/jquery.flot.js',
'main/webapp/bower_components/flot-spline/js/jquery.flot.spline.js',
'main/webapp/bower_components/flot.tooltip/js/jquery.flot.tooltip.js',
'main/webapp/bower_components/footable/js/footable.js',
'main/webapp/bower_components/html5sortable/jquery.sortable.js',
'main/webapp/bower_components/json3/lib/json3.js',
'main/webapp/bower_components/ng-grid/build/ng-grid.js',
'main/webapp/bower_components/intl-tel-input/build/js/intlTelInput.min.js',
'main/webapp/bower_components/intl-tel-input/lib/libphonenumber/build/utils.js',
'main/webapp/bower_components/ng-intl-tel-input/dist/ng-intl-tel-input.js',
'main/webapp/bower_components/ngImgCrop/compile/minified/ng-img-crop.js',
'main/webapp/bower_components/ngstorage/ngStorage.js',
'main/webapp/bower_components/ng-file-upload/ng-file-upload.js',
'main/webapp/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js',
'main/webapp/bower_components/oclazyload/dist/ocLazyLoad.min.js',
'main/webapp/bower_components/screenfull/dist/screenfull.js',
'main/webapp/bower_components/slimscroll/jquery.slimscroll.min.js',
'main/webapp/bower_components/textAngular/dist/textAngular.min.js',
'main/webapp/bower_components/venturocket-angular-slider/build/angular-slider.js',
'main/webapp/bower_components/videogular/videogular.js',
'main/webapp/bower_components/videogular-buffering/buffering.js',
'main/webapp/bower_components/videogular-controls/controls.js',
'main/webapp/bower_components/videogular-ima-ads/ima-ads.js',
'main/webapp/bower_components/videogular-overlay-play/overlay-play.js',
'main/webapp/bower_components/videogular-poster/poster.js',
'main/webapp/bower_components/waves/dist/waves.min.js',
'main/webapp/bower_components/angular-mocks/angular-mocks.js',
// endbower
'main/webapp/scripts/app/app.js',
'main/webapp/scripts/app/**/*.+(js|html)',
'main/webapp/scripts/components/**/*.+(js|html)',
'test/javascript/spec/helpers/module.js',
'test/javascript/spec/helpers/httpBackend.js',
'test/javascript/**/!(karma.conf|protractor.conf).js'
],
// list of files / patterns to exclude
exclude: ['test/javascript/e2e/**'],
preprocessors: {
'./main/webapp/scripts/**/*.js': ['coverage'],
'**/*.html': ['ng-html2js']
},
reporters: ['dots', 'jenkins', 'coverage', 'progress'],
jenkinsReporter: {
outputFile: '../build/test-results/karma/TESTS-results.xml'
},
coverageReporter: {
dir: '../build/test-results/coverage',
reporters: [
{type: 'lcov', subdir: 'report-lcov'}
]
},
// web server port
port: 9876,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true,
// to avoid DISCONNECTED messages when connecting to slow virtual machines
browserDisconnectTimeout : 10000, // default 2000
browserDisconnectTolerance : 1, // default 0
browserNoActivityTimeout : 4*60*1000 //default 10000
});
};
I'm stuck on writing unit test for last couple days as I find them quite confusing and not simple like in Java. Will appreciate any help.
The above expectation doesn't work because $scope.countries is undefined
^^ That's not true. It's not that $scope.countries is undefined, it's that result is undefined, and it's not the result you're trying to assign to $scope.countries, it's the one relating to $scope.timezones
I think this is your problem here:
MockTimezone.getTimezones.and.returnValue($q.resolve());
You're implicitly passing undefined into that resolve() function, and THAT'S throwing an error when you instantiate your controller.
It's throwing that error because you've got this line at the end of your controller:
$scope.loadTimezones();
It's for this reason that I stopped initializing controllers within themselves. Now I do it using ng-init, initiated from the HTML. If you make the same change as I did you won't encounter issues like this again in the future.
I am getting following service undefined error when i try to unit test a service call return in my app . I spend several hours on this , but i couldn't really isolate where the issue comes from . Appreciate if anyone could help me out with this .
Firefox 38.0.0 (Windows 8.1) companyService should return a promise for getCompany function FAILED
minErr/<#C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:63:12
loadModules/<#C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4138:15
forEach#C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:323:11
loadModules#C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4099:5
createInjector#C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4025:11
workFn#C:/Users/user1m/Documents/mycompany/WebApiRole/node_modules/angular-mocks/angular-mocks.js:2409:44
TypeError: companyService is undefined in C:/Users/user1m/Documents/mycompany/WebApiRole/test/company/Compa
nyServiceSpec.js (line 15)
#C:/Users/user1m/Documents/mycompany/WebApiRole/test/company/CompanyServiceSpec.js:15:16
Firefox 38.0.0 (Windows 8.1): Executed 1 of 1 (1 FAILED) ERROR (0.031 secs / 0.014 secs)
My karma.conf.js file
// Karma configuration
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: [
'node_modules/requirejs/require.js',
'bower_components/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'bower_components/ng-file-upload/**/*.js',
'bower_components/angular-ui-router/release/**/*.js',
'bower_components/angular-bootstrap/**/*.js',
'bower_components/angular-translate/**/*.js',
'bower_components/angular-translate-loader-static-files/**/*.js',
'bower_components/angular-pnotify/src/**/*.js',
'bower_components/angular-local-storage/**/*.js',
'bower_components/angular-loading-bar/build/**/*.js',
'app/app.js',
'app/**/*.js',
'test/**/*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
hostname: 'localhost',
port: 44555,
// 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: ['Firefox'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
CompanyServiceSpec.js file
'use strict';
describe('companyService', function() {
var $httpBackend, companyService;
beforeEach(angular.mock.module('mycompany'));
beforeEach(angular.mock.inject(function(_$httpBackend_, _companyService_) {
$httpBackend = _$httpBackend_;
companyService = _companyService_;
}));
it('should return a promise for getCompany function', function() {
expect(typeof companyService.getCompany('foobar').then).toBe('function');
});
});
CompanyService.js file
angular.module('mycompany').factory('companyService',
function($http, mycompanyApiProvider, $upload) {
'use strict';
var _company = null;
function getCompany(companyId) {
return $http.get(mycompanyApiProvider.url('companies/' + companyId));
}
});
app.js file
angular.module('mycompany', [
'ui.router',
'ui.router.util',
'angularFileUpload',
'pascalprecht.translate',
'jlareau.pnotify',
'LocalStorageModule',
'angular-loading-bar',
'ui.bootstrap',
'angularMoment',
'frapontillo.bootstrap-switch'
]);
angular.module('mycompany').run(function (mycompanyApiProvider, $state, userService, localStorageService,
$translate, $rootScope, $window, $timeout) {
'use strict';
mycompanyApiProvider.setEndpoint('/api/');
mycompanyApiProvider.loginUrl = '/home/login';
});
mycompanyApiProvider.js file
'use strict';
angular.module('mycompany')
.provider('mycompanyApiProvider', function($httpProvider, $provide) {
$provide.factory('jsonHeaderInterceptor', function() {
return {
'request': function(config) {
// config.headers['Content-Type'] = 'application/json';
return config;
}
};
});
});
Folder structure
Folder structure :
|WebApiRole/Karma.Conf.js
|WebApiRole/app/app.js
|WebApiRole/app/company/CompanyService.js
|WebApiRole/app/common/services/mycompanyApiProvider.js
|WebApiRole/test/company/CompanyServiceSpec.js
The companyService factory doesn't return anything, so it's treated as having returned undefined. The test seems to be testing that it returns an object with a getCompany function, so you can change it so it does:
angular.module('mycompany').factory('companyService', function($http, mycompanyApiProvider, $upload) {
'use strict';
var _company = null;
function getCompany(companyId) {
return $http.get(mycompanyApiProvider.url('companies/' + companyId));
}
return {
getCompany: getCompany
};
});
I copied the angularjs example for unit testing from here. As its just direct implementation of the example, i am confused with the error thrown.
I work in Linux and using Brackets to as IDE.
Please let know what is the missing element to run the jasmine tests.
Ouput of Jasmine
PasswordController encountered a declaration exception.
ReferenceError: module is not defined
controller.js
angular.module('app', [])
.controller('PasswordController', function PasswordController($scope) {
$scope.password = '';
$scope.grade = function() {
var size = $scope.password.length;
if (size > 8) {
$scope.strength = 'strong';
} else if (size > 3) {
$scope.strength = 'medium';
} else {
$scope.strength = 'weak';
}
};
});
controller-spec.js
describe('PasswordController', function() {
beforeEach(module('app'));
var $controller;
beforeEach(inject(function(_$controller_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$controller = _$controller_;
}));
describe('$scope.grade', function() {
it('sets the strength to "strong" if the password length is >8 chars', function() {
var $scope = {};
var controller = $controller('PasswordController', { $scope: $scope });
$scope.password = 'longerthaneightchars';
$scope.grade();
expect($scope.strength).toEqual('strong');
});
});
});
karma-conf.js
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-resource/angular-resource.js',
'app/controllers/*.js',
'test/controllers/*.js'
],
Karma Output
/var/www/html/angular-jasmine-testing $ kma start karma.conf.js
INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 41.0.2272 (Linux)]: Connected on socket vZCR4hAC8uU7LutFNVl3 with id 44440115
Chrome 41.0.2272 (Linux): Executed 1 of 1 SUCCESS (0.042 secs / 0.035 secs)
I managed to get your test working. See the plunkr below:
describe("PasswordController", function() {
beforeEach(module('app'));
var $scope = null;
beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
$controller('PasswordController', {
$scope: $scope
});
}));
describe("$scope.grade", function() {
it("sets the strength to 'strong' if the password length is >8 chars", function() {
$scope.password = "longerthaneightchars";
$scope.grade();
expect($scope.strength).toEqual("strong");
});
})
});
plunkr
it's the first time that i use angular application using generator and units tests with karma.
i wanna create some angularjs unit test for my app based on bower, gulp, karma...
this is my controller :
(function() {
'use strict';
angular.module('order', ['common'])
.controller('OrderVehiculesController', function (drivers,Logger) {
var self = this;
this.orderForm = {
id: '',
txt: ''
};
this.msgCtrlError = {
id: ''
};
var logger = Logger.getInstance('OrderVehiculesController');
logger.log(self);
this.getOrder = function (name) {
// A modifier car il serait plus judicieux d'avoir un model d'object et de pouvoir les réinitialiser avec une function
self.msgCtrlError.id = '';
self.msgCtrlError.txt = '';
drivers
.getOrder(name)
.then(function (orderData) {
self.orderData = orderData;
logger.log('orderData='+orderData);
logger.log('orderData name='+orderData.name);
})
.catch(function (err) {
logger.error('status=' + err.status + ' error=' + err.error);
self.msgCtrlError.id = err.status;
self.msgCtrlError.txt = err.error;
});
};
});
})();
and the [common] is like that :
(function() {
'use strict';
angular.module('common', [
'common.drivers-service',
'common.ads-auth-service',
'common.liferay-service',
'common.locale-service',
'common.logging-service'
]);
})();
and I tried to test it like that:
'use strict';
describe('orderModule', function () {
// Set up the module
beforeEach(module('common'));
beforeEach(module('order'));
var scope;
//test controller order
describe('OrderVehiculesController', function () {
var controller;
beforeEach(inject(function ($controller, $rootScope,common) {
scope = $rootScope.$new();
//TODO: how to call common mudule???
//instantiation of controller with its modules
controller = $controller('OrderVehiculesController', {
$scope: scope,
});
}));
it('should be defined', function() {
expect(OrderVehiculesController).toBeDefined();
});
});
});
but finaly, i've this error and i didn't understand it, i need some help please.
thank you.
ERROR is:
> WARN [watcher]: Pattern "C:\Users\src\**\*.mock.js" does not match any file.
> INFO [PhantomJS 1.9.8 (Windows 7)]: Connected on socket 4vwNDK9jjnvHoFW7eeL- with id 39484477
PhantomJS 1.9.8 (Windows 7) orderModule OrderVehiculesController should be defined FAILED
Error: [$injector:unpr] Unknown provider: commonProvider <- common
http://errors.angularjs.org/1.3.15/$injector/unpr?
and my karma config is the default karma.confg.js :
'use strict';
module.exports = function(config) {
var configuration = {
autoWatch : false,
frameworks: ['jasmine'],
ngHtml2JsPreprocessor: {
stripPrefix: 'src/',
moduleName: 'gulpAngular'
},
browsers : ['PhantomJS'],
plugins : [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
],
preprocessors: {
'src/**/*.html': ['ng-html2js']
}
};
// This block is needed to execute Chrome on Travis
// If you ever plan to use Chrome and Travis, you can keep it
// If not, you can safely remove it
// https://github.com/karma-runner/karma/issues/1144#issuecomment-53633076
if(configuration.browsers[0] === 'Chrome' && process.env.TRAVIS) {
configuration.customLaunchers = {
'chrome-travis-ci': {
base: 'Chrome',
flags: ['--no-sandbox']
}
};
configuration.browsers = ['chrome-travis-ci'];
}
config.set(configuration);
};
I've been looking through countless SO post on this but can't get the unit test of my angular controller to work.
Error:
TypeError: Object #<Object> has no method 'apply'
Error: [ng:areq] Argument 'CorrMatrixCtrl' is not a function, got undefined
http://errors.angularjs.org/1.2.14/ng/areq?p0=CorrMatrixCtrl&p1=not%20a%20function%2C%20got%20undefined
at /home/sebastian/gutenberg-for-good/app/lib/angular/angular.js:78:12
at assertArg (/home/sebastian/gutenberg-for-good/app/lib/angular/angular.js:1402:11)
at assertArgFn (/home/sebastian/gutenberg-for-good/app/lib/angular/angular.js:1412:3)
at /home/sebastian/gutenberg-for-good/app/lib/angular/angular.js:6881:9
at null.<anonymous> (/home/sebastian/gutenberg-for-good/test/unit/controllersSpec.js:28:20)
at Object.invoke (/home/sebastian/gutenberg-for-good/app/lib/angular/angular.js:3762:17)
at workFn (/home/sebastian/gutenberg-for-good/test/lib/angular/angular-mocks.js:2144:20)
Error: Declaration Location
at window.inject.angular.mock.inject (/home/sebastian/gutenberg-for-good/test/lib/angular/angular-mocks.js:2129:25)
at null.<anonymous> (/home/sebastian/gutenberg-for-good/test/unit/controllersSpec.js:26:33)
at /home/sebastian/gutenberg-for-good/test/unit/controllersSpec.js:1:1
Controller:
angular.module('gutenberg.controllers', ['ui.bootstrap'])
.controller('CorrMatrixCtrl', ['AnalysisFactory', '$scope', function(AnalysisFactory, $scope){
$scope.get = function() {
//something
};
}]);
Test:
describe("corrMatrixCtrl test", function() {
var fakeFactory = {
// some code
};
beforeEach(angular.module("gutenberg.controllers"));
it("should have a get method", inject(function($controller, $rootScope) { // line 26
var controller = $controller("CorrMatrixCtrl", {AnalysisFactory: fakeFactory, $scope: $rootScope.$new()}); // line 28
expect(angular.isFunction(controller.get)).toBe(true);
}));
});
From all the tutorials I've been reading or watching and all the documentation I can't see the error. Any kind of help is highly appreciated!
Karma config:
module.exports = function(config){
config.set({
basePath : '../',
files : [
'app/lib/angular/angular.js',
'app/lib/angular/angular-*.js',
'test/lib/angular/angular-mocks.js',
'app/js/**/*.js',
'test/unit/controllersSpec.js'
],
exclude : [
'app/lib/angular/angular-loader.js',
'app/lib/angular/*.min.js',
'app/lib/angular/angular-scenario.js'
],
autoWatch : true,
frameworks: ['jasmine'],
browsers : ['Chrome'],
plugins : [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine'
],
})}
First off, your defining the get method on the $scope, and not on the controller. So your test should be:
var scope = $rootScope.$new();
var controller = $controller("CorrMatrixCtrl", {AnalysisFactory: fakeFactory, $scope: scope});
expect(angular.isFunction(scope.get)).toBe(true);
If you wanted to define it on the controller, your controller code should be:
this.get = function() {
//something
};
That probably doesn't solve your problem though. My guess is that you don't include the controller code in the test. Add an alert/console.log at the top of the controller file and rerun the test to make sure that it's there.