Jasmine Unit Test Erroring out with angularjs factory - angularjs

I'm trying to adapt this answer to my creation and testing of a factory..
Failing unit test of factory with dependency in AngularJS using Jasmine & Karma
Anyhow, I'm getting this error..
Error: [$injector:unpr] Unknown provider: ModulizerFactoryProvider <-
ModulizerFactory
Here's my code, fairly blank, but should pass.
angular.module( 'modulizer', [
'ui.router',
'ui.bootstrap'
])
.factory('ModulizerFactory', function() {
function Modulizer(modules) {
this.modules = modules;
}
return Modulizer;
})
Here's my test:
describe( 'Modulizer', function() {
describe( 'make_apiUrlFn', function() {
var AppCtrl, $location, $scope;
beforeEach(module( 'modulizer' ) );
beforeEach( inject( function( $injector ) {
myFactory = $injector.get('ModulizerFactory');
}));
it( 'should exist', inject( function(myFactory) {
expect(myFactory).toBeDefined();
}));
});
});

So there were two things going on..
First, something was wonky with my grunt watch process, which was making none of my changes in the source file get applied.
Second, there is a bug in the test posted above...
describe( 'Modulizer', function() {
describe( 'make_apiUrlFn', function() {
var AppCtrl, $location, $scope;
beforeEach(module( 'modulizer' ) );
beforeEach( inject( function( $injector ) {
myFactory = $injector.get('ModulizerFactory');
}));
it( 'should exist', inject( function(ModulizerFactory) {
expect(myFactory).toBeDefined();
}));
});
});
The difference is in the 'should exist' line.

Related

"before each" hook: workFn error

I am running my tests with karma and phantom, Also I'm using mocha and sinon and tests are getting failed with below error:
EditResourceCategoryDialogTest EditResourceCategoryDialogController "before each" hook: workFn
Error: [$injector:modulerr] http://errors.angularjs.org/1.4.9/$injector/modulerr?p0=resourceofferingsApp&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20
Sample code:
define(function (require) {
"use strict";
var assert = require('chai').assert;
var sinon = require('sinon');
var angular = require('angular');
var angularMocks = require('angular.mocks');
require('resourceofferings/app');
require('dialog path');
describe('EditResourceCategoryDialogTest', function () {
beforeEach(module('resourceofferingsApp'));
describe('EditResourceCategoryDialogController', function () {
var $scope, ctrl;
//you need to inject dependencies first
beforeEach(inject(function ($rootScope, $injector) {
$scope = $rootScope.$new();
}));
it('initialization test (create mode)', inject(function ($controller) {
ctrl = $controller("EditResourceCategoryDialogController", {
$scope: $scope,
$uibModalInstance: null,
options: {
isEditMode: false
}
});
assert.equal($scope.isEditMode, false);
}));
});
});
});
Its exactly getting failed here:
beforeEach(inject(function ($rootScope, $injector) {
$scope = $rootScope.$new();
}));
Please help me to fix this issue..
Thanks in advance.
Try this ...
describe('controllers', function(){
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new(); // this is what you missed out
controller = $controller('EditResourceCategoryDialogController', {
$scope: scope,
$uibModalInstance: null,
options: {
isEditMode: false
}
});
}));
});
Update: According to Angular ...
A common reason why the module fails to load is that you've forgotten
to include the file with the defined module or that the file couldn't
be loaded.
Are you sure all needed files are loaded?

How to unit test angularjs route's resolve with karma and mocha+chai?

I am working on an app where I need to resolve promises in the router (ngRoute). The problem is that I am not sure how to write the unit tests for this, I am using karma with mocha and chai.
Here is the part of the code I'd like to test:
function config ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/orders.html',
controller: 'OrderController',
controllerAs: 'vmr',
resolve: OrderController.resolve,
data: {...}
});
}
function OrderController (OrderService, newOrders) {
this.newOrders = newOrders;
}
OrderController.resolve = {
newOrders: function (OrderService) {
return OrderService.getOrders();
}
};
This is how I started to write my unit tests when I didn't have the resolve part yet:
describe('OrderController', function() {
'use strict';
var controller,
service,
httpBackend;
beforeEach(module('myApp.orders'));
beforeEach(inject(function($controller, _OrderService_, $httpBackend) {
service = _OrderService_;
httpBackend = $httpBackend;
// Create the controller
controller = $controller('OrderController', {});
}));
beforeEach(function() {
httpBackend.when('GET', 'url/to/get/orders')
.respond(200, {[...]});
});
afterEach(function() {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
it('should get the list of new orders', function() {
httpBackend.flush();
expect(controller.neworders).not.to.undefined;
expect(controller.neworders.length).to.equal(3);
});
});
At this point is where I am getting the error:
Unknown provider: newOrdersProvider <- newOrders
I understand why I get this error, but I don't know how to solve it. Basically I don't know how to test the promise that resolves in the route.
Thanks in advance for your help!
After a lot of searching and reading the AngularJS Testing Cookbook I find out how to inject the result of the promise in the controller.
The main code doesn't change, so I will post here only the update code for the unit tests:
describe('OrderController', function() {
'use strict';
var controller,
service,
httpBackend;
// here is where I will inject a new value
beforeEach(function() {
module('myApp.orders', function($provide) {
$provide.value('resolver', {
newOrders: function(service) {
return service.getOrders();
}
});
});
});
beforeEach(inject(function($controller, _OrderService_, $httpBackend, resolver) {
service = _OrderService_;
httpBackend = $httpBackend;
// Create the controller
controller = $controller('OrderController', {
// add them to the controller
newOrders: resolver.newOrders(service)
});
}));
beforeEach(function() {
httpBackend.when('GET', 'url/to/get/orders')
.respond(200, {[...]});
});
afterEach(function() {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
it('should get the list of new orders', function() {
httpBackend.flush();
expect(controller.neworders).not.to.undefined;
expect(controller.neworders.length).to.equal(3);
});
});
If someone has a better/different solution I'd like to hear it as well!

Angular testing [$injector:unpr] Unknown provider: STARTUP_CONFIG

I'm having trouble getting my tests to run due to dependencies not beeing injected correctly.
The error I'm getting is defined in the title. I've included the actual test code, the app.js & index.html file from my solution.
The problem lies with the deferred bootstrap which I'm not fimiliar with as it was included by one of my colleagues. If I remove the "app.config(function (STARTUP_CONFIG..." from the app.js file then the test runs fine
How can I correctly inject the STARTUP_CONFIG in my test?
test code
..
..
describe("test description...", function () {
var app;
var mockupDataFactory;
beforeEach(module('Konstrukt'));
beforeEach(inject(function (STARTUP_CONFIG,BUDGETS,APPLICATIONS) {
//failed attempt to inject STARTUP_CONFIG
}));
beforeEach(function () {
app = angular.module("Konstrukt");
});
beforeEach(function () {
mockupDataFactory = konstruktMockupData.getInstance();
});
it('should be accessible in app module', function () {
expect(app.pivotTableService).toNotBe(null); //this test runs fine
});
it('test decr...', inject(function ( pivotTableService) {
... //Fails here
..
..
app.js
..
..
angular.module('Konstrukt', ['ngGrid', 'ngSanitize', 'ngRoute','pasvaz.bindonce', 'ngAnimate', 'nvd3ChartDirectives', 'ui.select', 'ngProgress', 'ui.grid', 'ui.grid.edit','ui.grid.selection', 'ui.grid.cellNav', 'ui.grid.pinning', 'ui.grid.resizeColumns']);
var app = angular.module('Konstrukt');
app.config(function (STARTUP_CONFIG, BUDGETS, APPLICATIONS) {
var STARTUP_CONFIG = STARTUP_CONFIG;
var BUDGETS = BUDGETS;
var APPLICATIONS = APPLICATIONS;
});
..
..
index.html
..
..
<script>
setTimeout(function(){
window.deferredBootstrapper.bootstrap({
element: window.document.body,
module: 'Konstrukt',
resolve: {
STARTUP_CONFIG: ['$http', function ($http) {
return $http.get('/scripts/_JSON/activeBudgets.JSON');
}],
BUDGETS: ['$http', function ($http) {
return $http.get('/scripts/_JSON/activeBudgets.JSON');
}],
APPLICATIONS: ['$http', function ($http) {
return $http.get('/scripts/_JSON/applications.JSON');
}]
}
})
} , 1500);
</script>
The deferredBootstrapper will not run in your unit tests, which means the constants it normally adds to your module won't be available.
You can add a global beforeEach that provides mocked versions of them:
beforeEach(function () {
module(function ($provide) {
$provide.constant('STARTUP_CONFIG', { something: 'something' });
$provide.constant('BUDGETS', { something: 'something' });
$provide.constant('APPLICATIONS', { something: 'something' });
});
});

Getting error in controller while unit testing using karma jasmine

I'm getting this error while I'm running unit test using Karma-Jasmine
ReferenceError: myModule is not defined
My sample test case is as follows..
describe("Unit Testing", function() {
beforeEach(angular.mock.module('myModule.common'));
var scope, ngTableParams, filter ,testTableParam;
it('should have a commonController controller', function () {
expect(myModule .common.controller('commonController ', function (commonController ) {
$scope:scope;
ngTableParams:ngTableParams;
$filter: filter;
tableParams: testTableParam
}
)).toBeDefined();
});});
I have injected the module name as myModule.common.
Can you please suggest a solution?
Try following code snippet it might help
describe('testing myModule.common', function() {
var $rootScope, $scope, $filter, $controller, ngTableParams, testTableParam;
beforeEach(module('myModule.common'));
beforeEach(function() {
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
$filter = $injector.get('$filter');
testTableParam = $injector.get('testTableParam');
ngTableParams = $injector.get('ngTableParams');
$controller = $injector.get('$controller')('commonController ', {
$scope: $scope
});
});
});
it('testing commonController ', function() {
expect('commonController ').toBeDefined();
});
});
It will solve your problem

AngularJS controller unit test with Jasmine

I'm making a unit test for an angular controller with Jasmine but I can't get passed the error
"TypeError: Cannot read property 'running' of undefined".
The full error is posted at the bottom.
Here's the app definition...
var myApp= myApp|| angular.module('myApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']);
myApp.run(['$http', '$rootScope', 'properties', function($http, $rootScope, properties) {
//...
//Implementation of custom dependency
properties.get().then(function(response) {
$rootScope.propertiesLoaded = true;
myApp.properties = response;
});
//...
}]);
The controller..
myApp.controller('myController', function($scope, users) {
//...
});
The test.js
describe("Test Controllers", function () {
beforeEach(function () {
angular.module("myApp");
//Injection of mocked custom dependency into the myApp.run method
myApp.run(function ($provide) {
$provide.provider('properties', function () {
this.$get = function () {
return "Mock return"
};
});
});
});
describe("myController", function () {
var scope, usrs, createMainController, mockDependency;
beforeEach(function () {
mockDependency = {
current: {
get: function () {
return "Mock return";
}
}
};
angular.module(function ($provide) {
$provide.value('users', mockDependency);
},[]);
inject(function (_$injector_, _$controller_, _$rootScope_, users) {
scope = _$rootScope_.$new();
usrs = _$injector_.get("users");
_$controller_("myController", {
$scope: scope,
users: usrs
});
createMainController = function () {
return _$controller_("myController", {
$scope: scope,
users: usrs
});
};
});
});
describe("This simple test", function () {
it("should pass no matter what", function () {
expect(true).toBe(true);
});
});
});
});
Here's the whole error message...
TypeError: Cannot read property 'running' of undefined
at isSpecRunning (file:///C:/.../angular-mocks.js:1923:73)
at window.inject.angular.mock.inject (file:///C:/.../angular-mocks.js:2087:20)
Next line points to inject function
at Object.<anonymous> (file:///C:/.../mySpec.js:37:13)
at attemptSync (file:///C:/.../jasmine.js:1510:12)
at QueueRunner.run (file:///C:/.../jasmine.js:1498:9)
at QueueRunner.execute (file:///C:/.../jasmine.js:1485:10)
at Spec.Env.queueRunnerFactory (file:///C:/.../jasmine.js:518:35)
at Spec.execute (file:///C:/.../jasmine.js:306:10)
at Object.<anonymous> (file:///C:/.../jasmine.js:1708:37)
at attemptAsync (file:///C:/.../jasmine.js:1520:12)
Here is a related reference to the error that I found which suggests it is an existing problem with Jasmine. However, in this case the problem involved Mocha, which I'm not using.
https://github.com/angular/angular.js/issues/1467
I'm not sure if this will help you, but you could give this a shot, I've had that problem. I'm not very good with AngularJS so if this doesn't work I don't know what to tell you. In your angular-mocks.js find the function isSpecRunning and change it into this:
function isSpecRunning() {
//return currentSpec && (window.mocha || currentSpec.queue.running);
return !!currentSpec;
}
I read something about Jasmine 2.0 (not sure if that's what you're on) not behaving unless you have this line.
They have fixed this issue using the above logic in newer version of angular-mocks.js (v 1.3.15).

Resources