I am getting this common error Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope with my test case . I know this is a common one , and there are few other threads explaining with solutions . But i really couldn't come up with a answer to my problem . Can anyone point me in the right direction?
ViewMeetingCtrl ,
(function () {
'use strict';
angular.module('MyApp').controller('ViewMeetingCtrl', ViewMeetingCtrl);
ViewMeetingCtrl.$inject = ['$scope', '$state', '$http', '$translate', 'notificationService', 'meetingService', '$modal', 'meeting', 'attachmentService'];
function ViewMeetingCtrl($scope, $state, $http, $translate, notificationService, meetingService, $modal, meeting, attachmentService) {
$scope.meeting = meeting;
$scope.test = "testvalue";
if (meeting.Status == 'Cancelled')
{
$scope.actionButtons = false;
}
else
{
$scope.actionButtons = true;
}
//more code
}
})();
MeetingCtrlSpec.js
describe('ViewMeetingCtrl', function () {
var $rootScope, scope, $controller, meetingService;
beforeEach(angular.mock.module('MyApp'));
beforeEach(inject(function ($rootScope, $controller, meetingService) {
scope = $rootScope.$new();
$controller('ViewMeetingCtrl', {
meetingService: meetingService,
'$rootScope' : $rootScope,
scope: scope
});
}));
it('should change greeting value if name value is changed', function () {
//some assertion
});
});
Error trace :
Firefox 37.0.0 (Windows 8.1) ViewMeetingCtrl should change greeting value if name value is changed FAILED
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- ViewMeetingCtrl
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20ViewMeetingCtrl
minErr/<#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:63:12
createInjector/providerCache.$injector<#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/ang
ular/angular.js:4015:19
getService#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:4162:39
createInjector/instanceCache.$injector<#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/ang
ular/angular.js:4020:28
getService#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:4162:39
invoke#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:4194:1
instantiate#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:4211:27
$ControllerProvider/this.$get</<#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/an
gular.js:8501:18
angular.mock.$ControllerDecorator</<#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/node_modules/angular-mo
cks/angular-mocks.js:1878:12
#C:/Users/dell pc/Documents/Work/MyApp/FLIS.Client.Tests/test/company/MeetingCtrlSpec.js:8:1
invoke#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/bower_components/angular/angular.js:4203:14
workFn#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/node_modules/angular-mocks/angular-mocks.js:2436:11
angular.mock.inject#C:/Users/dell%20pc/Documents/Work/MyApp/WebApiRole/node_modules/angular-mocks/angular-mocks
.js:2407:25
#C:/Users/dell pc/Documents/Work/MyApp/Client.Tests/test/company/MeetingCtrlSpec.js:6:16
#C:/Users/dell pc/Documents/Work/MyApp/Client.Tests/test/company/MeetingCtrlSpec.js:1:1
Firefox 37.0.0 (Windows 8.1): Executed 3 of 3 (1 FAILED) (0.094 secs / 0.091 secs)
Replace
$controller('ViewMeetingCtrl', {
meetingService: meetingService,
'$rootScope' : $rootScope,
scope: scope
});
by
$controller('ViewMeetingCtrl', {
meetingService: meetingService,
$scope: scope
});
The controller must be injected with an argument named $scope, not scope. And $rootScope is not part of the injected collaborators of your controller.
Same error I had forget to put '$' before scope in
app.controller("loginCtrl", function(**$**scope){
})
Related
This is the actual error message that I receive:
Uncaught Error: [$injector:unpr] Unknown provider: formsProvider <- forms <- SignupAcclaimController
this is at the start of my test file:
describe("SignUp", function() {
describe("SignupAcclaimController", function () {
beforeEach(module('CL.SignUp'));
var controller, SignupService, $state, scope, identity;
beforeEach(inject(function (_$controller_, _$state_, _SignupService_, _$rootScope_, _identity_) {
$state = _$state_;
scope = _$rootScope_.$new();
SignupService = _SignupService_;
identity = _identity_;
controller = _$controller_('SignupAcclaimController', {
$state: $state,
SignupService: SignupService,
identity: _identity_,
detailsForm: mocks.form
});
}));........
The error occurs when trying to set controller. mocks.form has been declared above this code.
The actual controller is:
(function() {
'use strict';
angular.module('CL.SignUp')
.controller('SignupAcclaimController', SignupAcclaimController);
SignupAcclaimController.$inject = ['$window', '$state', '$log', 'SignupService', 'identity', 'detailsForm', 'forms', '$rootScope', '$scope', '$timeout'];
function SignupAcclaimController($window, $state, $log, SignupService, identity, detailsForm, forms, $rootScope, $scope, $timeout) {
var vm = this, ........
If I change the injector functions signature to be the same as the method signature of the actual controller then expand the controller = to be
controller = _$controller_('SignupAcclaimController', {
$window: _$window_,
$state: $state,
$log: $log,
SignupService: SignupService,
identity: _identity_,
detailsForm: mocks.form,
forms: _forms_,
$scope: scope,
$rootScope: _$rootScope_,
$timeout: _$timeout_
then the error changes to :
Uncaught Error: [$injector:unpr] Unknown provider: formsProvider <- forms
I have a simple login controller:
'use strict';
angular.module('login', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
}])
.controller('LoginCtrl', ["$scope", "$route", "LoginService", function ($scope, $route, LoginService) {
var self = this;
this.showGuestLogin = true;
this.showUserLogin = false;
this.toggleUserLoginType = function () {
this.showGuestLogin = !this.showGuestLogin;
this.showUserLogin = !this.showUserLogin;
}
this.submitGuestLogin = function()
{
if(this.guestName === undefined || this.guestName.trim() == '')
{
self.loginError = "Name cannot be blank";
return;
}
LoginService.loginAsGuest(this.guestName.trim())
.then(function()
{
self.loginError = null;
$route.reload();
})
.catch(function(err)
{
self.loginError = 'An error occured. Please try again';
});
}
}]);
I am trying to test it with:
describe('LoginCtrl', function()
{
beforeEach(module('login'));
var ctrl;
beforeEach(inject(function($controller)
{
ctrl = $controller('LoginCtrl');
}));
it('should set error if guest name is undefined', function(done)
{
ctrl.guestName = undefined;
ctrl.submitGuestLogin();
expect(ctrl.loginError).toBeDefined();
});
});
But I am getting this error in console when test runs
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20LoginCtrl
I can see in the developer console in the karma driven browser that the controller and it's dependant files are all being loaded correctly.
I can't see what is wrong?
UPDATE
I have tried the suggestions of passing an empty object:
beforeEach(inject(function($controller, $scope, $route, LoginService)
{
ctrl = $controller('LoginCtrl', {
});
}));
and setting up the dependencies:
beforeEach(inject(function($controller, $scope, $route, LoginService)
{
ctrl = $controller('LoginCtrl', {
$scope: $scope,
$route: $route,
LoginService: LoginService
});
}));
Both of which give me this error:
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope
It's because you need to add in the scope in the injection like this:
beforeEach(inject(function($controller, $scope) {
ctrl = $controller('LoginCtrl', { $scope: $scope });
}));
Similarly, if your real controller has injections that you will be using for testing, you'll need to add them in. So for example (and this is only an example):
ctrl = $controller('LoginCtrl',
{
$scope: $scope,
SomeService: SomeService,
moment: moment,
dateFormat: dateFormat
});
Found an answer here which worked: Angular Unit Test Unknown provider: $scopeProvider
beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
scope = $rootScope.$new();
ctrl = $controller('LoginCtrl', {
$scope: scope
});
}));
In my case I didn't actually need $scope injected into my controller, so I removed it an the original code now works:
beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
ctrl = $controller('LoginCtrl');
}));
I need to read up on how mocks and injection works!
I have the following test case MeetingCtrlSpec.js
describe('ViewMeetingCtrl', function () {
var $rootScope, scope, $controller ;
beforeEach(angular.mock.module('MyApp'));
beforeEach(inject(function ($rootScope, $controller ) {
scope = $rootScope.$new();
$controller('ViewMeetingCtrl', {
$scope: scope,
});
}));
it('should change greeting value if name value is changed', function () {
//some assertion
});
});
ViewMeetingCtrl.js
(function () {
'use strict';
angular.module('MyApp').controller('ViewMeetingCtrl', ViewMeetingCtrl);
ViewMeetingCtrl.$inject = ['$scope', '$state', '$http', '$translate', 'notificationService', 'meetingService', '$modal', 'meeting', 'attachmentService'];
function ViewMeetingCtrl($scope, $state, $http, $translate, notificationService, meetingService, $modal, meeting, attachmentService) {
$scope.meeting = meeting;
//more code goes here
}
})();
this meeting comes from the app.routes.js file
.state('company.meeting', {
abstract: true,
url: '/meetings/:meetingId',
template: '<ui-view/>',
resolve: {
meeting: function(meetingService, $stateParams){
return meetingService
.getMeeting($stateParams.meetingId)
.then(function(response){
return response.data;
});
}
},
})
My problem is regarding the injection of meeting in this ctrl . I am not sure how to do inject that in my test case. I did like the following .
describe('ViewMeetingCtrl', function () {
var $rootScope, scope, $controller , meeting ;
beforeEach(angular.mock.module('MyApp'));
beforeEach(inject(function ($rootScope, $controller , meeting ) {
scope = $rootScope.$new();
$controller('ViewMeetingCtrl', {
$scope: scope,
meeting : meeting
});
}));
it('should change greeting value if name value is changed', function () {
//some assertion
});
});
... and i got this error Error: [$injector:unpr] Unknown provider: meetingProvider <- meeting
How do i inject meeting dependency to my test case . ?
Meeting is not a service, but an object that is injected when route is resolve. In you test case you should explicitly create the meeting dummy object.
beforeEach(inject(function ($rootScope, $controller,$q ) {
scope = $rootScope.$new();
$controller('ViewMeetingCtrl', {
$scope: scope,
meeting : {} //your custom object
});
}));
Remember you are testing the controller in your test not the route resolution injection.
I'm having issues attempting to use the $scope service in my controller. The controller is basically taken from the angular-seed project.
'use strict';
angular.module('regApp.nameAddress', ['ngRoute'])
.config([
'$routeProvider', function($routeProvider) {
$routeProvider.when('/nameAddress', {
templateUrl: 'views/NameAddress.html',
controller: 'NameAddressController'
});
}
])
.controller('NameAddressController', ['$scope',
function($scope) {
$scope.x = 1;
}
]);
Here's the Jasmine test code I'm using:
'use strict';
describe('regApp.nameAddress module', function() {
beforeEach(function() { module('regApp.nameAddress') });
describe('Name and Address Controller', function () {
var scope;
var httpBackend;
beforeEach(inject(function ($rootScope, $controller, $injector) {
scope = $rootScope.$new();
httpBackend = $injector.get("$httpBackend");
$controller("NameAddressController", {
$scope: scope
});
}));
it('should exist', inject(function($controller) {
//spec body
var sut = $controller("NameAddressController");
expect(sut).toBeDefined();
}));
});
});
And when I run the test here is the error and stack trace I'm getting:
15 specs, 1 failure Spec List | Failures
regApp.nameAddress module Name and Address Controller should exist
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
http://errors.angularjs.org/1.2.28/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
http://errors.angularjs.org/1.2.28/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope
at Anonymous function (http://localhost:30489/js/lib/angular/angular.js:3801:13)
at getService (http://localhost:30489/js/lib/angular/angular.js:3929:11)
at Anonymous function (http://localhost:30489/js/lib/angular/angular.js:3806:13)
at getService (http://localhost:30489/js/lib/angular/angular.js:3929:11)
at invoke (http://localhost:30489/js/lib/angular/angular.js:3953:9)
at instantiate (http://localhost:30489/js/lib/angular/angular.js:3976:7)
at Anonymous function (http://localhost:30489/js/lib/angular/angular.js:7315:7)
at Anonymous function (http://localhost:30489/specs/NameAddressController_tests.js:25:13)
at invoke (http://localhost:30489/js/lib/angular/angular.js:3965:7)
at workFn (http://localhost:30489/js/lib/angular-mocks/angular-mocks.js:2177:11)
undefined
It has to be like this (you miss the $scope parameter in your second call to $controller):
'use strict';
describe('regApp.nameAddress module', function() {
var sut;
beforeEach(function() { module('regApp.nameAddress') });
describe('Name and Address Controller', function () {
var scope;
var httpBackend;
beforeEach(inject(function ($rootScope, $controller, $injector) {
scope = $rootScope.$new();
httpBackend = $injector.get("$httpBackend");
sut = $controller("NameAddressController", {
$scope: scope
});
}));
it('should exist', inject(function($controller) {
//spec body
expect(sut).toBeDefined();
}));
});
});
In your test, you're instantiating the controller without passing it a $scope:
$controller("NameAddressController");
That is not allowed. $scope is not an injectable service. It must be created and passed explicitely to the controller, as you're doing in your beforeEach() function.
.controller('ClientsCtrl', ['$scope', '$location', '$filter', '$modal', 'ngTableParams',
function($scope, $location, $filter, $modal, ngTableParams) {
var trowser = PY.getBooks($scope, $location, $modal);
};
controllertestspec.js
'use strict';
describe('suite', function() {
var scope, ctrl;
beforeEach(module('clients'));
beforeEach(inject(function($controller) {
scope = {};
var modalInstance = jasmine.createSpy('fakeModal');
ctrl = $controller('ClientsCtrl', {
$scope: scope,
$modal: modalInstance
});
}));
it('should change greeting value if name value is changed', function() {
});
});
I have added the js file having module PY and if i try to print console.log(typeof PY.Books) it shows as function.
When i tried to run the spec file am getting error
Chrome 39.0.2171 (Mac OS X 10.9.5) clients module should change greeting value if name value is changed FAILED
TypeError: undefined is not a function
at Object.PY.getBooks