Tests Failing due to socket io does not exist - javascript

io with my own angular service. I'm using yeoman and angular workflow: http://yeoman.io/ I need to make io recognised by karma so the test does not fail?
'use strict';
angular.module('publicApp')
.factory('socket', function ($rootScope) {
var socket = io.connect();
return {
on: function on(eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function emit(eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
});
}
};
});
angular.module('publicApp')
.controller('MainCtrl', function ($scope, socket) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'];
socket.on('person:added', function (data) {
$scope.person = data;
});
});
angular.module('publicApp', [])
.config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
});
'use strict';
describe('Controller: MainCtrl', function () {
// load the controller's module
beforeEach(module('publicApp'));
var MainCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('MainCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
io is part of window, I've tried using angulars $window object but had no luck. The error I'm getting from karma is:
Running "karma:unit" (karma) task
WARN [karma]: Port 8080 in use
INFO [karma]: Karma v0.10.2 server started at http://localhost:8081/
INFO [launcher]: Starting browser Chrome
WARN [watcher]: Pattern "/Users/michaeljames/Documents/Projects/StackOverflow/public/test/mock/**/*.js" does not match any file.
INFO [Chrome 29.0.1547 (Mac OS X 10.8.2)]: Connected on socket LmbsWIC-97zMEi76FmiE
Chrome 29.0.1547 (Mac OS X 10.8.2) Controller: MainCtrl should attach a list of awesomeThings to the scope FAILED
ReferenceError: io is not defined
at Object.$get (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/scripts/services/socket.js:5:16)
at Object.invoke (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:3000:28)
at /Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:2838:37
at getService (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:2960:39)
at invoke (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:2978:13)
at Object.instantiate (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:3012:23)
at /Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:4981:24
at null.<anonymous> (/Users/michaeljames/Documents/Projects/StackOverflow/public/test/spec/controllers/main.js:14:16)
at Object.invoke (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular/angular.js:3000:28)
at workFn (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular-mocks/angular-mocks.js:1795:20)
Error: Declaration Location
at window.jasmine.window.inject.angular.mock.inject (/Users/michaeljames/Documents/Projects/StackOverflow/public/app/bower_components/angular-mocks/angular-mocks.js:1781:25)
at null.<anonymous> (/Users/michaeljames/Documents/Projects/StackOverflow/public/test/spec/controllers/main.js:12:14)
at /Users/michaeljames/Documents/Projects/StackOverflow/public/test/spec/controllers/main.js:3:1
TypeError: Cannot read property 'length' of undefined
at null.<anonymous> (/Users/michaeljames/Documents/Projects/StackOverflow/public/test/spec/controllers/main.js:20:31)
Chrome 29.0.1547 (Mac OS X 10.8.2): Executed 1 of 1 (1 FAILED) ERROR (0.306 secs / 0.067 secs)
Warning: Task "karma:unit" failed. Use --force to continue.
Aborted due to warnings.

I'd mock the entire socket service, since this is a means of going to some sort of server and these unit tests should be about testing your UI code only (the reason for $httpBackend in ngMock).
Here are some clever guys that figured it out:
https://github.com/btford/angular-socket-io-seed/issues/4#issuecomment-14505212.

In your karma.config.js files section inject the server side socket.io.js
files: [
'test/unit/**/*.js',
'any/other/included/files/*.js',
'http://localhost:8080/socket.io/socket.io.js' //just only inject it
],

Related

Set correctly SignalR-hub configuration with AngularJS

I following this tutorial to implement push notifications with SignalR and toastr
before implement it my app.js is like:
(function () {
'use strict';
var app = angular.module('myPortal', ['common.core', 'common.ui'])
.config(config)
.run(run);
/* Setup global settings */
app.factory('settings', ['$rootScope', function ($rootScope) {
// supported languages
var settings = {....
when I update it as tutorial I have something like this:
(function () {
'use strict';
var app = angular.module('myPortal', ['common.core', 'common.ui'])
.config(config)
.run(run);
$(function () {
$.connection.hub.logging = true;
$.connection.hub.start();
});
$.connection.hub.error(function (err) {
console.log('An error occurred: ' + err);
});
angular.module('app')
.value('notification', $.connection.notification)
.value('toastr', toastr);
/* Setup global settings */
app.factory('settings', ['$rootScope', function ($rootScope) {
// supported languages
var settings = {...
but now my app crash and chrome console throw these issues:
angular.js:68 Uncaught Error: [$injector:nomod] Module 'app' is not
available! You either misspelled the module name or forgot to load it.
If registering a module ensure that you specify the dependencies as
the second argument.
and
Uncaught Error: [$injector:unpr] Unknown provider: settingsProvider <-
settings
What am I doing wrong? Regards

How can I test this Angular controller?

I'm discovering Karma great world and I wanted to ask you a simple question about a controller I want to test. Here it is :
angular.module('app', ['ngSanitize'])
.controller('MyController', ['$scope', '$http', function ($scope, $http) {
$scope.myCtrlData = '';
$http.get('../../data/file.json').then(function (res) {
$scope.myCtrlData = res.data.ctrlData;
});
}]);
It simply feed $scope.myCtrlData with a local json file content.
I started to write a quick test but I am stuck when running it.
describe('Test : MyController', function() {
var scope, httpBackend, make;
beforeEach(module('ngSanitize'));
beforeEach(module('app'));
beforeEach(inject(function($rootScope, $controller, $httpBackend){
httpBackend = $httpBackend;
scope = $rootScope.$new();
httpBackend.whenGET('../../data/file.json')
.respond(200, {
'data': { 'ctrlData': 'Yeah' }
});
make = $controller('MyController', { '$scope': scope });
}));
it('should get the data', function() {
httpBackend.flush();
expect(scope.myCtrlData).toBeDefined();
expect(scope.myCtrlData).toEqual('Yeah');
});
});
As a result I get a fail with this log :
PhantomJS 2.1.1 (Mac OS X 0.0.0) BioController should get the data FAILED
Expected undefined to equal 'Yeah'.
/Users/toto/Projects/awesomeproject/tests/views/yeah/test.js:32:30
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) (0 secs / 0.01 secsPhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.002 secs / 0.01 secs)
Could you please help me to figure out what did I do wrong ?
Thank you very much for your precious help :-)
You need to instantiate the controller.
make = $controller('MyController', { '$scope': scope });
with
$controller('MyController', { '$scope': scope });
Also,
can you modify your code
it('should get the data', function() {
httpBackend.whenGET('../../data/file.json')
.respond(200, {
'data': { 'ctrlData': 'Yeah' }
});
expect(scope.myCtrlData).toBeDefined();
expect(scope.myCtrlData).toEqual('Yeah');
httpBackend.flush();
});
Remove the httpBackend from the beforeEach and check

AngularJS Jasmine test: TypeError: 'undefined' is not an object

New to Angular and following up from my earlier post from angularjs jasmine tests: Variable vm not found
I am having a TypeError in my angular tests and not sure what the problem is. Here is my test:
(function(){
'use strict';
describe('Testing DeliveriesController', function() {
beforeEach(module('app.deliveries'));
describe('Testing deliveries controller', function(){
var vm, controller;
beforeEach(inject(function($controller, $rootScope){
vm = $rootScope.$new();
controller = $controller('DeliveriesController', {$scope:vm});
}));
afterEach(function() {
vm = undefined;
controller = undefined;
});
describe('priorities length', function(){
it('it should test priority length', function () {
expect(vm.priorities.length).toBe(0);
});
});
});
});
})();
The error I get is as follows:
PhantomJS 1.9.8 (Mac OS X 0.0.0) Testing DeliveriesController Testing deliveries controller priorities length it should test priority length FAILED
Error: [$injector:unpr] Unknown provider: DeliveriesServiceProvider <- DeliveriesService <- DeliveriesController
http://errors.angularjs.org/1.3.20/$injector/unpr?p0=DeliveriesServiceProvider%20%3C-%20DeliveriesService%20%3C-%20DeliveriesController
at /Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4031
at getService (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4178)
at /Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4036
at getService (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4178)
at invoke (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4210)
at instantiate (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4227)
at /Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:8524
at /Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular-mocks/angular-mocks.js:1916
at /Users/rgoti/ingestion/external-ingestion/app/public/src/app/deliveries/deliveries.spec.js:12
at invoke (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular/angular.js:4219)
at workFn (/Users/rgoti/ingestion/external-ingestion/app/public/bower_components/angular-mocks/angular-mocks.js:2475)
undefined
TypeError: 'undefined' is not an object (evaluating 'vm.priorities.length')
at /Users/rgoti/ingestion/external-ingestion/app/public/src/app/deliveries/deliveries.spec.js:23
Courtesy: comment from #StubbbOrn:
Could you show controller's code? It would help to understand problem better. Looks like DeliveriesController depends not only on $scope but also on DeliveriesService. When you instantiate controller you should provide it all dependencies (either real or mocked ones).
This solution worked for me and was the solution. Thanks #StubbOrn
Looks like you are using DeliveriesService in your controller.
Whenever you are using a service, you need to make sure either you inject that service or add it using a $provider.
beforeEach(inject(function($controller, $rootScope, _DeliveriesService_){
vm = $rootScope.$new();
DeliveriesSrvc = _DeliveriesService_;
controller = $controller('DeliveriesController', {$scope:vm});
}));
or
beforeEach(module(function ($provide) {
mockObj = {
functionName: jasmine.createSpy('functionName')
}
$provide.value('DeliveriesService',mockObj)
}));

injections issues in unit testing using karma angularjs

I need to test a controller with a lot of injections (services, factories, values), now I have a problem with a value...
I have the following situation:
This is my controller.
(function () {
'use strict';
angular
.module('otpConfigureDatasets')
.controller('otpConfigureDatasetsController', otpConfigureDatasetsController);
otpConfigureDatasetsController.$inject = ['$location', '$state', 'otpWebMapApp', 'otpWMDeltaTracker', 'otpWMStateCache', '$scope', '$timeout', 'otpConfigureDatasetService', 'otpAllDatasetsService', 'otpReviewListDatasetsService','otpConfigureDatasetSelectedTab'];
function otpConfigureDatasetsController($location, $state, otpWebMapApp, otpWMDeltaTracker, otpWMStateCache, $scope, $timeout, otpConfigureDatasetService, otpAllDatasetsService, otpReviewListDatasetsService, otpConfigureDatasetSelectedTab) {
var vm = this;
...
vm.tabs = [{
title: 'MY REVIEW LIST',
selectedAmt: vm.reviewData,
contentTemplate: './app/features/configureDatasets/reviewListDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
}, {
title: 'ALL DATASETS',
selectedAmt: vm.allData,
contentTemplate: './app/features/configureDatasets/allDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
}];
...
}
})();
My Spec.js below
'use strict';
describe('Test', function () {
var MainCtrl, scope, _otpWebMapApp_, _otpWMDeltaTracker_, _otpWMStateCache_, _otpConfigureDatasetService_,
_otpAllDatasetsService_, _otpReviewListDatasetsService_, _otpConfigureDatasetSelectedTab_;
beforeEach(function () {
module('otpConfigureDatasets');
});
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
it('Should be true', function () {
expect(true).toBe(true);
});
});
But when I try to run the test case, It doesn´t work and display the following error:
INFO [karma]: Karma v0.12.37 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8 0.0.0)]: Connected on socket NHknSeC3p_h_lf12SK Gh with id 27552356
PhantomJS 1.9.8 (Windows 8 0.0.0) Test Should be true FAILED
TypeError: 'undefined' is not an object (evaluating 'otpConfigureDatasetSelectedTab.tab')
at otpConfigureDatasetsController (D:/workspace/.....
I already have all the required files in the karma.config.js....
If I comment these two lines in the controller.
//active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
and
//active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
The unit testing works fine.
What´s wrong in my Spec definition???
You are not saving the object you're trying to mock. You basically have just
_otpConfigureDatasetService_ = undefined,
_otpReviewListDatasetsService_ = undefined
So it's not the controller that is failing, it's the unit test. You're injecting undefined in place of both objects. I'm not sure what you want to do exactly, but you either need to define some mock objects like _otpConfigureDatasetService_ = {tab: 'something'} or get the real services and adjust them
beforeEach(inject(function ($controller, $rootScope, otpConfigureDatasetService, otpReviewListDatasetsService) {
//
_otpConfigureDatasetService_ = otpConfigureDatasetService;
_otpReviewListDatasetsService_ = otpReviewListDatasetsService;
//
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
BTW the convention is to define _object_ in the inject function and then to save it. If you inject them how they're called then you don't need to use _object_ form for your local variables.
I also prefer to use the $injector
beforeEach( inject(function($injector) {
exampleService = $injector.get('exampleService');
}));

Angular testing with Karma: after injecting controller, $controller() is undefined

I'm trying to set up testing for Angular with Karma and Jasmine. I've successfully installed and configured Karma, but I'm having trouble using angular-mocks. Below in aTest.spec.js I include a simple app, controller, and test spec to illustrate the problem. Can anyone tell me what I'm doing wrong?
My console output from Karma:
Chrome 39.0.2171 (Mac OS X 10.8.5) ControllerForTest encountered a declaration exception FAILED
TypeError: undefined is not a function
at Suite.<anonymous> (/Users/duncanmalashock/python_projects/scout/public/tests/unit/aTest.spec.js:19:20)
at jasmineInterface.describe (/Users/duncanmalashock/python_projects/scout/node_modules/karma-jasmine/lib/boot.js:59:18)
at /Users/duncanmalashock/python_projects/scout/public/tests/unit/aTest.spec.js:13:1
Chrome 39.0.2171 (Mac OS X 10.8.5): Executed 1 of 1 (1 FAILED) ERROR (0.004 secs / 0.002 secs)
karma.conf.js:
...
files: [
'http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js',
'angular/vendor/angular-mocks.js',
'tests/unit/*.spec.js'
],
...
Controller:
var testApp = angular.module('testApp', []);
testApp.controller('ControllerForTest', ['$scope',
function($scope) {
$scope.data = {
a: 'foo',
b: 'bar',
c: 'baz'
};
}
]);
aTest.spec.js:
describe('ControllerForTest', function() {
module('testApp');
var $controller;
inject(function(_$controller_) {
$controller = _$controller_;
});
var controller = $controller('ControllerForTest');
it('is defined', function() {
expect($controller).toBeDefined();
});
});
Module instantiation and service injection should happen in a beforeEach, not directly within a describe block. This will make them available to each of the following its.
You also don't need to test $controller, that's an Angular service. Test your controller instead.
describe('ControllerForTest', function() {
var $controller;
var ControllerForTest;
beforeEach(function() {
module('testApp');
inject(function(_$controller_) {
$controller = _$controller_;
});
});
it('is defined', function() {
// This line can also be in the beforeEach.
// Saves having to repetitively instantiate the controller.
ControllerForTest = $controller('ControllerForTest');
expect(ControllerForTest).toBeDefined();
});
});

Categories

Resources