Reputation: 441
I am using custom provider in my app.js to make backend call and then in controllers just injecting that provider and getting promise result (I make this because instead to call getLoggedUser in every controller I am just getting results from provider) and instead of making 10 calls for example I will make just one in provider). But I am unable to test this provider $get method and test is failing because backend call is never made.
I am getting error :
Error: Unexpected request: GET https://localhost:8443/user/current
app.js
angular.module('app', [
...
])
.config(config)
.run(run)
.controller('MainCtrl', MainCtrl)
.value('version', '1.1.0')
.provider('userProvider', function(){
this.$get = ['AuthenticationService',
function(AuthenticationService) {
return AuthenticationService.getLoggedUser();
}];
});
TEST
/* jshint undef:false*/
(function() {
'use strict';
describe('ListingController', function() {
var listingController, rootScope, scope, q, mockAuthenticationService, $httpBackend, service;
var provider = {};
var mockCurrentUser = {
id: 1782,
name: "One, Coordinator",
roleId: [
3, 10
],
eauthId: "coodinator1"
};
beforeEach(module('app'));
beforeEach(module('listing'));
beforeEach(function () {
module(function (userProviderProvider) {
provider = userProviderProvider;
});
});
beforeEach(inject(function($rootScope, $controller, $q, _$httpBackend_, _AuthenticationService_, userProvider, $injector) {
rootScope = $rootScope;
scope = rootScope.$new();
$httpBackend = _$httpBackend_;
q = $q;
mockAuthenticationService = _AuthenticationService_;
// provider = userProvider;
service = $injector.invoke(provider.$get);
rootScope.$digest();
listingController = $controller('ListingController', {
$scope : scope,
mockAuthenticationService : _AuthenticationService_
});
}));
describe('getLogged user and init',function(){
it("should call getLogged function", function() {
listingController.getLoggedUser();
rootScope.$digest();
expect(service).toHaveBeenCalled();
});
});
});
})();
Controller
function getLoggedUser() {
userProvider.then(function (data){
// Here I am getting result from back end call from provider which is good
});
If I make something like this in provider:
this.$get = function (AuthenticationService) {
return {
loggedUser : function() {
return AuthenticationService.getLoggedUser();
}
}
}
I can then make something like this in test:
spyOn(provider , 'loggedUser').and.callFake(function() {
var deferred = q.defer();
deferred.resolve(mockCurrentUser);
return deferred.promise;
});
and this will work test will pass, but with this approach in every controlle when I user userProvider.loggedUser().then it will make additional back end call and with above one only once back end call will be made.
Update for Ceylan
If I do like you suggest to call service and in method call getLoggedUser from another service additional calls are being made every time...not just one like I have without function.
.provider('userProvider', function(){
return {
$get: function(AuthenticationService) {
return new userService(AuthenticationService);
}
}
});
service
function userService(AuthenticationService) {
this.getLoggedUser = function() {
return AuthenticationService.getLoggedUser();
}
}
Upvotes: 0
Views: 418
Reputation: 527
Here is the basic structure:
$httpBackend.when('GET', 'localhost:8443/user/current').respond(200, /*optional response callback function*/);
$httpBackend.expect('GET', 'localhost:8443/user/current');
//here goes the function that makes the actual http request
$httpBackend.flush();
Be sure that you define your httpBackend var - var httpBackend = $httpBackend;
.
And also in order to check did the service was called, you must use spy.
spyOn(service, 'method').and.callThrough();
//here goes the function that calls the service
expect(service.method).toHaveBeenCalled();
You combine the two blocks above and you should be able to achieve what you want.
describe('something',function(){
it("should do something", function() {
spyOn(service, 'method').and.callThrough();
$httpBackend.when('GET', 'localhost:8443/user/current').respond(200,/*optional response callback function*/);
$httpBackend.expect('GET', 'localhost:8443/user/current');
//call the function that makes http request and calls your service
rootScope.$digest();
$httpBackend.flush();
expect(service.method).toHaveBeenCalled();
});
});
And about your service:
function myService(){
var svc = this;
svc.myMethod = function(){
return someDataOrPromise;
}
}
Upvotes: 0