Angular: Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope [duplicate] - javascript

This question already has answers here:
Angular Unit Test Unknown provider: $scopeProvider
(2 answers)
Closed 7 years ago.
Yet another question about injecting $scope into tests and services :-) Learning angular and using angular-seed application as a start.
I have extended my controller to have $scope but now my default angular seed tests are failing with
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
I don't understand is the error with my controller or with my tests...
View/Controller/Service
(function () {
"use strict";
angular.module("app.view1", ["ngRoute"])
.config(["$routeProvider",
function ($routeProvider) {
$routeProvider.when("/view1", {
templateUrl: "views/view1/view1.html",
controller: "View1Ctrl"
});
}
])
.factory("User", ["$http",
function ($http) {
var User = {};
User.get = function () {
return $http.get("/api/v1/user");
};
return User;
}
])
.controller("View1Ctrl", ["$scope", "User",
function ($scope, User) {
User.get().success(
function (response) {
$scope.user = response;
});
}
]);
}());
Test
'use strict';
describe('app.view1 module', function() {
beforeEach(module('app.view1'));
describe('view1 controller', function(){
it('should ....', inject(function($controller) {
//spec body
var view1Ctrl = $controller('View1Ctrl');
expect(view1Ctrl).toBeDefined();
}));
});
});
Application is working and I get to see data in HTML but tests are failing... all suggestions welcome!

I was missing $scope in the test, here is updated test that works:
'use strict';
describe('app.view1 module', function() {
beforeEach(module('app.view1'));
describe('view1 controller', function() {
it('should ....', inject(function($controller, $rootScope) {
//spec body
var $scope = $rootScope.$new(),
ctrl = $controller('View1Ctrl', {
$scope: $scope,
$User: {}
});
expect(ctrl).toBeDefined();
}));
});
});

Your are in a test, there is no DOM, and no $scope.
Your can deal with this by passing locals to the $controller service, like this :
var $scope = {};
var view1Ctrl = $controller('View1Ctrl', { $scope: $scope });

Related

karma test controller using toBeDefined failed

My test failed because it says my controller is not defined. So strange I think I did everything right.
describe('homeCtrl', function() {
var httpBackend, controller, scope;
beforeEach(module('App'));
beforeEach(inject(function($httpBackend, $controller) {
scope = {};
httpBackend = $httpBackend;
controller = $controller('homeCtrl', { $scope: scope });
}));
it('should exist', function() {
expect(controller).toBeDefined();
});
});
and I have my home.js which is the controller like this
var App = angular.module('App')
App.controller('homeCtrl', function($scope) {
})
The error is Expected undefined to be defined.
Your home.js should have dependencies injected in module, change it as,
var App = angular.module('App',[])
App.controller('homeCtrl', function($scope) {
})

Injecting dependencies into Angular services for testing

I'm trying to do some test driven development of an angular service I'm writing using Jasmine. However, I seem to have stumbled at the first hurdle, and I cannot get my $resource dependency to resolve.
The error I get is
Unknown provider: $resourceProvider <- $resource <- lookupService
My code is as follows
Module:
(function() {
'use strict';
angular
.module('common', ['ngSanitize', 'ngAnimate']);
})();
Service:
(function() {
'use strict';
angular
.module('common')
.service('lookupService', lookupService);
lookupService.$inject = ['$resource', 'api'];
function lookupService($resource, api) {
return {
getLookup: getLookup
};
function getLookup() {
return "something";
}
}
})();
Test:
describe('Service tests',
function () {
var lookupService, mockApi, $httpBackend;
//mocks
beforeEach(function () {
mockApi = { getUri: jasmine.createSpy() };
angular.mock.module('common',
function ($provide) {
$provide.value('api', mockApi);
});
});
//injects
beforeEach(function () {
inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
lookupService = $injector.get('lookupService');
});
});
//tests
it('should be able to return something',
inject(function () {
expect(lookupService.getLookup()).toEqual("something");
}));
});//Service tests
The angular-resource.js file is included in my runner file. I'm not sure where I'm going wrong, any help would be appreciated.
Thanks
ngResource must be a dependency:
(function() {
'use strict';
angular
.module('common', ['ngSanitize', 'ngAnimate', 'ngResource']);
})();

AngularJS and Jasmine: mocking services

I am having trouble mocking the dependency of the following service "broadcaster" over the service "pushServices".
angular.module('broadcaster', ['pushServices']);
angular.module('broadcaster').service('broadcaster', [
'$rootScope', '$log', 'satnetPush',
function ($rootScope, $log, satnetPush) {
// .. contents ..
};
};
The Jasmine spec is as follows:
describe('Test Broadcaster Service', function () {
'use strict';
var broadcasterService, mockPushService;
beforeEach(module('broadcaster'));
beforeEach(inject(function($injector) {
broadcasterService = $injector.get('broadcaster');
mockPushService = {
getSomething: function () { return 'mockReturnValue'; }
};
module(function ($provide) {
$provide.value('satnetPush', mockPushService);
});
}));
it('should return a non-null broadcaster object', function () {
expect(broadcasterService).not.toBeNull();
});
});
The error that I get is the typical "Unknown provider":
PhantomJS 1.9.8 (Linux) Test Broadcaster Service should return a non-null broadcaster object FAILED
Error: [$injector:unpr] Unknown provider: $pusherProvider <- $pusher <- satnetPush <- broadcaster
http://errors.angularjs.org/1.3.14/$injector/unpr?p0=%24pusherProvider%20%3C-%20%24pusher%20%3C-%20satnetPush%20%3C-%20broadcaster
What am I doing wrong? How should I be injecting the dependency instead?
The key is to $provide your mock service before you get the service under test from $injector. Then the 'satnetPush' will exist:
describe('Test Broadcaster Service', function () {
'use strict';
var broadcasterService, mockPushService;
beforeEach(function() {
module('broadcaster');
module(function ($provide) {
mockPushService = {
getSomething: function () { return 'mockReturnValue'; }
};
$provide.value('satnetPush', mockPushService);
});
inject(function($injector) {
broadcasterService = $injector.get('broadcaster');
})
});
it('should return a non-null broadcaster object', function () {
expect(broadcasterService).not.toBeNull();
});
});
Here's a working fiddle

$scopeProvider <- $scope/ Unknown provider

I testing my angular-application with jasmine(http://jasmine.github.io/2.0/) and getting next error:
Unknown provider: $scopeProvider <- $scope
I know, that it's incorrect to build dependency with scope in filters, services, factories, etc., but I use $scope in controller!
Why am i getting this error? controller looks like
testModule.controller('TestCont', ['$filter', '$scope', function($filter, $scope){
var doPrivateShit = function(){
console.log(10);
};
this.lol = function(){
doPrivateShit();
};
this.add = function(a, b){
return a+b;
};
this.upper = function(a){
return $filter('uppercase')(a);
}
$scope.a = this.add(1,2);
$scope.test = 10;
$scope.search = {
};
}]);
and my test's code:
'use strict';
describe('testModule module', function(){
beforeEach(function(){
module('testModule');
});
it('should uppercase correctly', inject(function($controller){
var testCont = $controller('TestCont');
expect(testCont.upper('lol')).toEqual('LOL');
expect(testCont.upper('jumpEr')).toEqual('JUMPER');
expect(testCont.upper('123azaza')).toEqual('123AZAZA');
expect(testCont.upper('111')).toEqual('111');
}));
});
You need to manually pass in a $scope to your controller:
describe('testModule module', function() {
beforeEach(module('testModule'));
describe('test controller', function() {
var scope, testCont;
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
testCont = $controller('TestCont', {$scope: scope});
}));
it('should uppercase correctly', function() {
expect(testCont.upper('lol')).toEqual('LOL');
expect(testCont.upper('jumpEr')).toEqual('JUMPER');
...
});
});
});
Normally, a $scope will be available as an injectable param only when the controller is attached to the DOM.
You need to associate somehow the controller to the DOM (I'm mot familiar with jasmine at all).
I am following a video tutorial from egghead (link bellow) which suggest this approach:
describe("hello world", function () {
var appCtrl;
beforeEach(module("app"))
beforeEach(inject(function ($controller) {
appCtrl = $controller("AppCtrl");
}))
describe("AppCtrl", function () {
it("should have a message of hello", function () {
expect(appCtrl.message).toBe("Hello")
})
})
})
Controller:
var app = angular.module("app", []);
app.controller("AppCtrl", function () {
this.message = "Hello";
});
I am posting it because in the answer selected we are creating a new scope. This means we cannot test the controller's scope vars, no?
link to video tutorial (1min) :
https://egghead.io/lessons/angularjs-testing-a-controller

Error: [$injector:unpr] Unknown provider in jasmine test when routeprovider service is injected in a controller

I have created an application in angular js, in which i am using ng-view for navigating templates, from routeProvider i am injecting a service called customerDetail to all templates. when i wrote a jasmine testcase for injecting customerDetail services into the CustomerReportController constructor, but i am getting
<failure type="">Error: [$injector:unpr] Unknown provider: customerDetailProvider <- customerDetail
can anyone please tell me some solution for this
main/customerReport/main.spec.js
describe('tsi', function()
{
var $scope, customerDetail;
beforeEach(module('tsi.customerReport'));
beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
CustomerReportController = $controller('CustomerReportController', {
$scope: $scope,
customerDetail: customerDetail
});
}));
it('test CustomerReportController', inject(function() {
expect(CustomerReportController).toBeTruthy();
}));
});
main.js
angular.module( 'tsi', ['tsi.customerDetail', 'ngRoute'])
.config(function(RestangularProvider, $routeProvider)
{
RestangularProvider.setBaseUrl('/customer/service/detail');
$routeProvider.when('/customerDetail',
{
templateUrl: 'main/main.tpl.html',
controller: 'CustomerDetailController',
resolve: {
customerDetail: function(CustomerDetailService) {
return CustomerDetailService.getServiceDetail();
}
}
}).when('/customerReport',
{
templateUrl: 'main/customerReport/main.tpl.html',
controller: 'CustomerReportController',
resolve: {
customerDetail: function(CustomerDetailService) {
return CustomerDetailService.getServiceDetail();
}
}
}).otherwise(
{
redirectTo: '/customerDetail'
});
})
.factory('CustomerDetailService', function(Restangular) {
return {
getCustomerDetail: function() {
return Restangular.one('user/customerDetail').get().then(function(customerDetail) {
return customerDetail;
});
}
};
});
main/customerReport/main.js
angular.module('tsi.customerReport', [])
.controller('CustomerReportController', function($scope, $http, $filter, $timeout, customerDetail)
{
$scope.customerOrderDetails = customerDetail;
:
:
});
the same problem faced by me..
what I did was that I included all the services there in my js file. make sure all the services and providers are injected properly
here is an example code for jasmine unit testing.
describe('UserService',function() {
var scope, DataService, UserService, http, cookieStore;
beforeEach(module('app'));
beforeEach(inject(function ($http, _DataService_) {
http = $http;
DataService = _DataService_;
}));
it('getProfilePicture', function () {
http.post('/api/getProfilePicture', function (data) {
expect(data).toBeDefined();
});
});
});
DataService is my service here

Categories