AngularJS routing test Unknown provider - angularjs

I'm trying to set jasmine test on router like this
it('should map routes to controllers and templates', function() {
inject(function($route) {
module('igt');
expect($route.routes['/'].controller).toBe('mainPageCtrl');
expect($route.routes['/'].templateUrl).toEqual('html/pages/main.html');
// otherwise redirect to
expect($route.routes[null].redirectTo).toEqual('/')
});
});
and my router file is (only beggining because it's long):
(function () {
'use strict';
angular
.module('igt')
.config(configure);
configure.$inject = ['$routeProvider', '$httpProvider'];
function configure($routeProvider, $httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'html/pages/main.html',
controller: 'mainPageCtrl'
})
And I did inject those files in karma.conf.js file:
// list of files / patterns to load in the browser
files: [
'../../node_modules/angular/angular.js',
'../../node_modules/angular-mocks/angular-mocks.js',
'../app.js',
'../router.js',
'unit/*.js'
],
And now when I start test with karma start it's giving me error:
Error: [$injector:unpr] Unknown provider: $routeProvider <- $route
My entire JS code is encapsulated in IIFE so I don't have even one global variable (I don't know if it matter).
Why I have this error what I'm doing wrong?

Change it as
describe('Testing Routes', function () {
beforeEach(module('myApp'));
it('should map routes to controllers and templates', function($route) {
expect($route.routes['/'].controller).toBe('mainPageCtrl');

Related

AngularJS karma jasmine test can't find route provider

I have angular script post.js and test for it post_test.js.
my post.js file
var Post = angular.module('Post', []);
Post
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/post', {
controller: 'PostCtrl',
templateUrl: 'src/posts/partials/post.html'
})
;
}]);
and my post_test.js file:
'use strict';
describe('Post module', function() {
beforeEach(module('Post'));
describe('Post controller', function(){
it('should ....', inject(function($controller) {
//spec body
var PostCtrl = $controller('PostCtrl');
expect(PostCtrl).toBeDefined();
}));
});
});
in karma.conf.js I load
files: [
'app/components/angular/angular.js',
'app/components/angular-route/angular-route.js',
'app/components/angular-mocks/angular-mocks.js',
'app/app.js',
'app/src/**/*.js' // post.js, post_test.js
],
Everything seems OK, but angular returns this error:
Error: [$injector:modulerr] Failed to instantiate module Post due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
I don't know why. I load angular-route.js before post.js. I've checked and it loads correctly. I've put alert(1) before defining $routeProvier and I've seen it in console. So this file is loading correctly, but in next file - test file it still doesn't work.
ngRoute module should be loaded as well.
Replace:
var Post = angular.module('Post', []);
with:
var Post = angular.module('Post', ['ngRoute']);

Define/use angularjs controller inside internal module

I use Typescript 1.4 with angularjs 1.3.6.
Using VS 2015 RC with webessentials, with no module system (no --module flag)
I have a working code like this:
demoModule.ts
module Demo.Test {
'use strict';
(() => {
var app = angular.module('Demo.Test', []);
// Routes.
app.config([
'$stateProvider', $stateProvider => {
$stateProvider
.state('demo', {
url: '/demo',
templateUrl: '/views/test/demo.html',
controller: 'demoController as vm'
});
}
]);
})();
demoController.ts
module Demo.Test {
'use strict';
export class DemoController {
constructor(/* ... */) { /* ... */}
}
angular.module('Demo.Test').controller('demoController', Demo.Test.DemoController);
}
But when I move this line:
angular.module('Demo.Test').controller('demoController', Demo.Test.DemoController);
to the demoModule.ts file(see below) it will compile, but getting JS error when run:
Error: [ng:areq] Argument 'demoController' is not a function, got undefined
Any idea how can I make it work? I mean like this:
module Demo.Test {
'use strict';
(() => {
var app = angular.module('Demo.Test', []);
angular.module('Demo.Test').controller('demoController', Demo.Test.DemoController);
// Routes.
app.config([
'$stateProvider', $stateProvider => {
$stateProvider
.state('demo', {
url: '/demo',
templateUrl: '/views/test/demo.html',
controller: 'demoController as vm'
});
}
]);
})();
If you used the script reference not in the right order, then you are going to get the runtime error.
as: Error: [ng:areq] Argument 'demoController' is not a function, got undefined
Add demoController.ts before demoModule.ts in your html file.
<script src="demoController.js"></script>
<script src="demoModule.js"></script>
Its got to do with ordering of files. One of the well known errors caused by using --out in TypeScript : https://github.com/TypeStrong/atom-typescript/blob/master/docs/out.md#runtime-errors

Injecting routerProvider for AngularJS test using Jasmine

I'm using Jasmine for testing AngularJS controller and I'm struggling to find a way of injecting $routeProvider into the module.
Here's my controller:
var app = angular.module('testApp', []);
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/smth', {
templateUrl: 'smth.html',
controller: 'testController'
});
}]);
app.controller('testController', ['$scope', function ($scope) {
$scope.data = 'GG';
}]);
Here's my test:
describe('Test Suite', function () {
var myScope, ctrl;
beforeEach(module('testApp'));
beforeEach(inject(function ($controller, $rootScope) {
myScope = $rootScope.$new();
ctrl = $controller('testController', {
$scope: myScope
});
}));
it('data is GG', function () {
expect(myScope.data).toEqual('GG');
});
});
When I try to run it, I receive a following error:
Error: [$injector:modulerr] Failed to instantiate module testApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
But if I try to run again - I get this:
TypeError: 'undefined' is not an object (evaluating 'myScope.data')
Errors keep alternating if tests are run again. I'm using Visual Studio 2013 and Resharper 8 to run the Jasmine tests.
Add the angular-route bower component to your project and then inject the ngRoute into your module like this
var app = angular.module('testApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/smth', {
templateUrl: 'smth.html',
controller: 'testController'
});
}]);
app.controller('testController', ['$scope', function ($scope) {
$scope.data = 'GG';
}]);
First make sure you have included angular-route.min.js.
This module has been separated from angularJs library, so you have will have to include it separately
then make sure you have added dependency for your module to ngRoute
e.g. angular.module('testApp', ['ngRoute']);
then in the test make sure you inject $route so its available in your tests as well

jasmine test for $routeprovider resolve in config block

i have the below in my module config block:
var appModule = angular.module('myApp',['ngRoute'])
.config(['$httpProvider', '$routeProvider', '$locationProvider', '$translateProvider', function ($httpProvider, $routeProvider, $locationProvider, $translateProvider) {
$locationProvider.html5Mode(true)
$routeProvider
.when('/services/main', {templateUrl: '/services/main/html/main.html', controller: 'MainCtrl', resolve: {
myVar: function (varService) {
return varService.invokeService();
}
}})
}])
Spec File:
describe("Unit Testing: config - ", function() {
var appModule;
var routes;
beforeEach(function() {
appModule = angular.module("myApp");
});
it('should test routeProvider', function() {
inject(function($route, $location, $rootScope) {
routes = $route;
});
});
});
however, while running the test i am getting the below error:
Unit Testing: config - should test routeProvider FAILED
Error: [$injector:unpr] http://errors.angularjs.org/1.2.15/$injector/unpr?p0=%24routeProvider%20%3C-%20%24route
at Error (native)
my karma config includes the angular-route.min.js file. Any suggestions will be helpful.
The issue was resolved with use of angular.mock.module instead of angular.module.
appModule = angular.mock.module("myApp");
What i found that we should use mock to inject the module and it includes the configuration as well where as module is used to register a newly module. So if one is refering to the module already registered, we should use angular.mock.module.
The documentaion says:
This function registers a module configuration code. It collects the configuration information which will be used when the injector is created by inject.

Angular.js configuring ui-router child-states from multiple modules

I'd like to implement a setup where i can define a "root state" in the main module, and then add child states in other modules. This, because i need the root state to resolve before i can go to the child state.
Apparently, this should be possible according to this FAQ:
How to: Configure ui-router from multiple modules
For me it doesn't work:
Error Uncaught Error: No such state 'app' from ngBoilerplate.foo
Here is what i have:
app.js
angular.module( 'ngBoilerplate', [
'templates-app',
'templates-common',
'ui.state',
'ui.route',
'ui.bootstrap',
'ngBoilerplate.library'
])
.config( function myAppConfig ( $stateProvider, $urlRouterProvider ) {
$stateProvider
.state('app', {
views:{
"main":{
controller:"AppCtrl"
}
},
resolve:{
Auth:function(Auth){
return new Auth();
}
}
});
$urlRouterProvider.when('/foo','/foo/tile');
$urlRouterProvider.otherwise( '/foo' );
})
.factory('Auth', ['$timeout','$q', function ($timeout,$q) {
return function () {
var deferred = $q.defer();
console.log('before resolve');
$timeout(function () {
console.log('at resolve');
deferred.resolve();
}, 2000);
return deferred.promise;
};
}])
.run(function run( $rootScope, $state, $stateParams ) {
console.log('greetings from run');
$state.transitionTo('app');
})
.controller( 'AppCtrl', function AppCtrl ( $scope, Auth ) {
console.log('greetings from AppCtrl');
});
foo.js
angular.module( 'ngBoilerplate.foo', ['ui.state'])
.config(function config( $stateProvider ) {
$stateProvider
.state( 'app.foo', {
url: '/foo/:type',
views: {
"main": {
controller:'FooCtrl',
templateUrl: function(stateParams) { /* stuff is going on in here*/ }
}
}
});
})
.controller( 'FooCtrl', function FooCtrl( $scope ) {
console.log('deferred foo');
});
How do i make this work or what other approaches could i take to have something global resolved before every state (without defining a resolve on each state)?
I finally chose this approach which does the job for me:
// add all your dependencies here and configure a root state e.g. "app"
angular.module( 'ngBoilerplate', ['ui.router','templates-app',
'templates-common','etc','etc']);
// configure your child states in here, such as app.foo, app.bar etc.
angular.module( 'ngBoilerplate.foo', ['ngBoilerplate']);
angular.module( 'ngBoilerplate.bar', ['ngBoilerplate']);
// tie everything together so you have a static module name
// that can be used with ng-app. this module doesn't do anything more than that.
angular.module( 'app', ['ngBoilerplate.foo','ngBoilerplate.bar']);
and then in your app index.html
<html ng-app="app">
In the documentation the feature1 module depends on the application module. Try
angular.module( 'ngBoilerplate.foo', ['ngBoilerplate'])
I would of just commented but i do not have the rep. I know this is old but i had the same problem and came across this. One thing i am confused about is in app.js you do not import "ngBoilerplate.foo" but ngBoilerplate.library instead. I had the same problem and my solution was to inject sub modules into the top module instead of their parent.
My structure was module('ngBoilerplate'), module('ngBoilerplate.foo') and module('ngBoilerplate.foo.bar')'. I was injecting ngBoilerplate.foo.bar into ngBoilerplate.foo and the $stateProvider was failing. I needed to inject ngBoilerplate.foo.bar into top level ngBoilerplate.
I thought i would put this here in case anyone else sees this. The error i had was Uncaught TypeError: Cannot read property 'navigable' of undefined from ngBoilerplate.foo

Resources