shireef khatab shireef khatab - 3 months ago 63
AngularJS Question

Getting error on angularJs unit testing using Karma and Jasmine

i'm trying to perform a unit test with Karma and Jasmine but i get error ,, looking at my code and result can u help me fixing this issue please? I'm too new to this so the solution could be too simple..Thank you.

My Karma configuration:

// 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: [
'bower_components/angular/angular.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/angular-mocks/angular-mocks.js',
'app/scripts/*.js',
'test/unit/**/*.js'
],

// list of files to exclude
exclude: [
'test/protractor.conf.js', 'test/e2e/*.js'
],
// 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
port: 9876,

// 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: ['Chrome','PhantomJS', 'PhantomJS_custom'],

// you can define custom flags
customLaunchers: {
'PhantomJS_custom': {
base: 'PhantomJS',
options: {
windowName: 'my-window',
settings: {
webSecurityEnabled: false
},
},
flags: ['--load-images=true'],
debug: true
}
},

phantomjsLauncher: {
// Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
exitOnResourceError: true
},

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}


My controller:

describe('Controller: MenuController', function () {

// load the controller's module
beforeEach(module('confusionApp'));

var MenuController, scope, $httpBackend;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, _$httpBackend_, $rootScope, menuFactory){
// place here mocked dependencies
$httpBackend = _$httpBackend_;
$httpBackend.expectGET("http://localhost:3000/dishes").respond([
{
"id": 0,
"name": "Uthapizza",
"image": "images/uthapizza.png",
"category": "mains",
"label": "Hot",
"price": "4.99",
"description": "A",
"comments":[{}]
},
{
"id": 1,
"name": "Zucchipakoda",
"image": "images/zucchipakoda.png",
"category": "mains",
"label": "New",
"price": "4.99",
"description": "A",
"comments":[{}]
}
]);
scope = $rootScope.$new();
MenuController = $controller('MenuController', {
$scope: scope, menuFactory: menuFactory });
$httpBackend.flush();

it('should have showDetails as false', function () {

expect(scope.showDetails).toBeFalsy();

});

it('should create "dishes" with 2 dishes fetched from xhr', function(){

expect(scope.showMenu).toBeTruthy();
expect(scope.dishes).toBeDefined();
expect(scope.dishes.length).toBe(2);

});

it('should have the correct data order in the dishes', function() {

expect(scope.dishes[0].name).toBe("Uthapizza");
expect(scope.dishes[1].label).toBe("New");

});

it('should change the tab selected based on tab clicked', function(){

expect(scope.tab).toEqual(1);

scope.select(3);

expect(scope.tab).toEqual(3);
expect(scope.filtText).toEqual('mains');

});
}));

});


This is what is on Chrome

Karma v1.1.1 - connected
Chrome 51.0.2704 (Windows 10 0.0.0) is idle
PhantomJS 2.1.1 (Windows 8 0.0.0) is idle
PhantomJS 2.1.1 (Windows 8 0.0.0) is idle
Chrome 51.0.2704 (Windows 10 0.0.0) is idle


And this is Terminal report:

PS D:\programming\web\angular.js\gulp\conFusion\test> karma start karma.conf.js
16 07 2016 17:49:04.773:WARN [karma]: No captured browser, open http://localhost:9876/
16 07 2016 17:49:04.820:INFO [karma]: Karma v1.1.1 server started at http://localhost:9876/
16 07 2016 17:49:04.835:INFO [launcher]: Launching browsers Chrome, PhantomJS, PhantomJS_custom with unlimited concurrency
16 07 2016 17:49:05.007:INFO [launcher]: Starting browser Chrome
16 07 2016 17:49:05.054:INFO [launcher]: Starting browser PhantomJS
16 07 2016 17:49:19.550:INFO [launcher]: Starting browser PhantomJS
16 07 2016 17:49:19.561:INFO [phantomjs.launcher]: ACTION REQUIRED:
16 07 2016 17:49:19.562:INFO [phantomjs.launcher]:
16 07 2016 17:49:19.564:INFO [phantomjs.launcher]: Launch browser at
16 07 2016 17:49:19.571:INFO [phantomjs.launcher]: http://localhost:9000/webkit/inspector/inspector.html?page=2
16 07 2016 17:49:19.575:INFO [phantomjs.launcher]:
16 07 2016 17:49:19.579:INFO [phantomjs.launcher]: Waiting 15 seconds ...
16 07 2016 17:49:21.051:INFO [Chrome 51.0.2704 (Windows 10 0.0.0)]: Connected on socket /#YCvvpIyKkfV8Zt7uAAAA with id 31119843
16 07 2016 17:49:21.728:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket /#1j0xHL_FNxuWzb3TAAAB with id 96164824
16 07 2016 17:49:36.243:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket /#9xpNc4LhgBzDKWEfAAAC with id 44407334
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 0 of 0 ERROR (0.005 secs / 0 secs)
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 0 of 0 ERROR (0.005 secs / 0 secs)
Chrome 51.0.2704 (Windows 10 0.0.0): Executed 0 of 0 ERROR (0.039 secs / 0 secs)
16 07 2016 17:50:18.653:INFO [Chrome 51.0.2704 (Windows 10 0.0.0)]: Connected on socket /#_CyPLIKTHNnT1d0HAAAD with id manual-8566
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 0 of 0 ERROR (0.004 secs / 0 secs)
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 0 of 0 ERROR (0.008 secs / 0 secs)
Chrome 51.0.2704 (Windows 10 0.0.0): Executed 0 of 0 ERROR (0.007 secs / 0 secs)
Chrome 51.0.2704 (Windows 10 0.0.0): Executed 0 of 0 ERROR (0.012 secs / 0 secs)


Update: i moved the tests outside inject, but it seems i got errors in my project ..
but still also can see errors related to testing itself..
here is what i get :

here is the screenshot

what about these errors , are they related to the testing code or just showing the result of my test?

PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 4 of 4 (4 FAILED) ERROR (0.038 secs / 0.055 secs)
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 4 of 4 (4 FAILED) ERROR (0.047 secs / 0
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 4 of 4 (4 FAILED) ERROR (0.038 secs / 0.055 secs)
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 4 of 4 (4 FAILED) ERROR (0.047 secs / 0.059 secs)
Chrome 52.0.2743 (Windows 10 0.0.0): Executed 4 of 4 (4 FAILED) ERROR (0.117 secs / 0.057 secs)

Answer

You have included your modular tests inside the inject function, so you should re-write the code asĀ“:

beforeEach(inject(function  ($controller, _$httpBackend_,   $rootScope, menuFactory){
                //  place   here    mocked  dependencies                        
                    $httpBackend =  _$httpBackend_;                     
                    $httpBackend.expectGET("http://localhost:3000/dishes").respond([
                    {
                  "id": 0,...
},
                  {
                  "id": 1, ..

                  }]);
                    scope   =   $rootScope.$new();
                    MenuController =    $controller('MenuController',   {                       
                    $scope: scope,  menuFactory:    menuFactory });
                    $httpBackend.flush();   
  }));

and after injection include tests:

it('should have showDetails as false', function () {

    expect(scope.showDetails).toBeFalsy();

  });

after this edit just be careful that $httpBackend is expect to GET localhost:3000 but before that if you are using ngRoute it will GET templates so you should handle that issue as well.