Injecting dependencies into Angular services for testing - javascript

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']);
})();

Related

AngularJS factory unit testing with dependencies

I am trying to test some AngularJS factories with Jasmine. It works fine for factories that don't have any dependencies. One of my factories uses Angular Material's $mdToast as dependency.
The factory:
(function() {
'use strict';
angular
.module('myModule')
.factory('ToastFactory', ToastFactory);
ToastFactory.$inject = ['$mdToast'];
function ToastFactory($mdToast) {
var service = {
showToast1: showToast1,
showToast2: showToast2
};
return service
function showToast1() {
return $mdToast.show($mdToast.build({
templateUrl: 'path'
}));
}
function showToast2() {
return $mdToast.show($mdToast.build({
templateUrl: 'path'
}));
}
}
})();
And here is one of the working tests for another factory without dependencies.
describe('myFactory', function() {
//Injector Service
var $injector;
//Set Module
beforeEach(function() {
angular.module('myModule');
});
//Inject injector service
beforeEach(inject(function() {
$injector = angular.injector(['myModule']);
}));
describe('SampleTest', function() {
it('should be true', function() {
//Arrange
var factory = $injector.get('myFactory');
//Act
var res = factory.testMethod();
//Assert
expect(res).toBe(true);
});
});
})
I know how to do it for controllers, but not for factories.

'homecntrl' is not a function, got undefined in angularjs

I am trying to test my controller .I am able to make simple controller in angular js and able to test controller online .here is my code
http://plnkr.co/edit/xzvhXHPoUdulOM9clOkQ?p=preview
controller code
(function(){
'use strict';
angular.module('app.home').controller('homeCntrl',homeCntrl);
function homeCntrl(){
var home=this;
home.clickbtn=function(){
home.message='test';
alert(home.message)
}
}
})();
but when test in my pc it not run and getting this error
**Argument 'homecntrl' is not a function, got undefined
http://errors.angularjs.org/1.4.8/ng/areq?p0=homecntrl&p1=not%20a%20function%2C%20got%20undefined
at /Users/naveenkumar/Documents/ionic_work/SimpleDemo/bower_components/angular/angular.js:68:12**
here is my code of test
(function(){
'use strict'
describe('http controller test', function() {
var $rootScope,
$scope,
controller,
$q,
$httpBackend;
beforeEach(function() {
module('app');
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
controller = $injector.get('$controller')('homecntrl', {
$scope: $scope
})
})
})
describe('Init value', function() {
it('check name value', function() {
expect(controller.message).toBeUndefined();
})
})
it('it should be true', function() {
expect(true).toBeTruthy();
})
})
})()
I am able to test online but not able to test on pc
here is my code of pc
https://dl.dropbox.com/s/no901z41bza7osm/SimpleDemo.zip?dl=0
please download it and go to project directory and write npm install
You should update your controller name homeCntrl to homecntrl
(function(){
'use strict';
angular.module('app.home').controller('homecntrl',homeCntrl);
function homecntrl(){
var home=this;
home.clickbtn=function(){
home.message='test';
alert(home.message)
}
}
})();
It will be work.

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

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 });

writing jasmine unit test for angular factory

I am trying to test an angular factory using jasmine and mocha however I keep getting undefined errors.
here is my factory:
(function() {
'use strict';
angular.module('app').factory('appFactory', appFactory);
appFactory.$inject = ['$http','$q'];
function appFactory($http,$q) {
return {
get: get
};
function get(someData) {
//....
}
}
})();
and here is my unit test using jasmine and mocha:
'use strict';
describe('Factory: appFactory', function() {
var http, appFactory;
var $rootScope, $scope;
beforeEach(function() {
angular.module('app');
});
beforeEach(inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
}));
beforeEach(inject(function() {
var $injector = angular.injector(['ngMock', 'ng', 'app']);
appFactory = $injector.get('appFactory');
}));
it('should be defined', inject( function() {
alert(appFactory);
}));
});
so my alert looks something like:
Object{get: function get(someData) {...}
how do I go about testing the functionality of my factory if this is returning an object?

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

Categories