In my controller I am using $resource: ng.resource.IResourceService the could help me to fetch data from the server.
controllers.controller("testController", [
"$scope", "$resource", "$rootScope", "$http",
"$window", "$location", "resourceService",
function ($scope, $resource: ng.resource.IResourceService, $rootScope: IRootScope,
$http, $window, $location, resourceService: services.IResourceService) { ...//implementation
}]);
And here is my attempt of Jasmine unit test. However, I am getting
Error: [$injector:unpr] Unknown provider: $resourceProvider <- $resource
How would you mock $resourceProvider?
describe("testController Tests", function (): void {
var vm: createDailylog.IViewModel;
var $scope: ng.IScope;
var $rootScope;
var $httpBackend: ng.IHttpBackendService;
//var $injector = angular.injector(['ng', 'ngResource']);
var $resource = $injector.get('$resource');
beforeEach(function (): void {
module("controllers");
});
beforeEach(inject(function (_$controller_: ng.IControllerService,
_$httpBackend_, _$resource_, _$rootScope_: IRootScope, $injector) {
$httpBackend = _$httpBackend_;
//$resource = _$resource_;
this.$httpBackend = $httpBackend;
$rootScope = _$rootScope_.$new();
$rootScope.config = {
serverUrl: "https://test.domainName.net/",
serverVersion: "test",
title: "Test Server Reference"
};
//instantiating controller
vm = _$controller_('testController', {
$scope: $scope,
$resource: $injector.get("$resource"),
$rootScope: _$rootScope_,
$window: {},
$location: {}
});
}));
//afterEach(function () {
// $httpBackend.verifyNoOutstandingExpectation();
// $httpBackend.verifyNoOutstandingRequest();
//});
describe('when populate method is called', function () {
it("should create controller!", function () {
$httpBackend.flush();
expect(true).toBe(true);
});
});
);
});
});
Why do you need to mock $resource? You should only be mocking data, which is coming from $http; you seem to be doing that already.
Related
Using Jasmine and chutzpah unable to access the $scope and $rootscope inside the success of http call.
In the jasmine code the var test = $rootScope.langCode is coming as 'undefined'. Which is inside the success callback of $http from factory.
Following are the controller code need to be tested.
app.controller('catalogCtrl', ['$scope', '$rootScope', '$window', 'catalogService', '$routeParams', '$location', '$timeout', '$filter', function ($scope, $rootScope, $window, catalogService, $routeParams, $location, $timeout, $filter) {
$scope.init = function (callback, params) {
catalogService.labeldata().then(function successCallback(response) {
$rootScope.langCode = "test";
}, function errorCallback(response) {
console.log(JSON.parse(JSON.stringify(response)));
$rootScope.langCode = "test1";
});
};
}]);
Following is the Factory where am doing the http call
app.factory('catalogService', ['$http', function ($http) {
return {
labeldata: function () {
return $http({
method: 'GET',
url: "/Content/Index/"
});
}
}
}]);
Jasmine code to test catalogCtrl
describe('catalogCtrl', function () {
var httpBackend, $rootScope, $scope, createController, authRequestHandler, myservice, $controller, $q;
beforeEach(module('catalogModule'));
beforeEach(function () {
module('catalogModule');
inject(function (_$controller_, _$rootScope_, $injector, _$q_) {
// inject removes the underscores and finds the $controller Provider
$controller = _$controller_;
$rootScope = _$rootScope_;
$scope = _$rootScope_.$new();
// Injecting Service references and HttpBackend Object :-
httpBackend = $injector.get('$httpBackend');
$q = _$q_;
myserv = $injector.get('catalogService');
});
});
it('Catalog Content', function () {
var $scope = {}; var $rtScope = {};
// $controller takes an object containing a reference to the $scope
var controller = $controller('catalogCtrl', { $scope: $scope, $rtScope: $rootScope });
// the assertion checks the expected result
var obj = { "COUNTRYCODE": "au", "KEY": "MERCHANDISE", "LANGCODE": "en", "VALUE": "Merchandise" };
var arr = [obj];
var returnData = {};
returnData.data = arr;
//returnData = arr;
//httpBackend.expectGET("/Content/Index/").respond(returnData);
httpBackend.when('GET', "/Content/Index/").respond(returnData);
var returnedData;
myserv.labeldata().then(function (returnData) {
// check that returned result contains
returnedData = result;
expect(returnedData).toEqual({ bar: 'foo' });
});
$scope.init();
var test = $rootScope.langCode;
});
});
I am trying to do unit test of my angular app with karma. I am getting some error. Am i missing something? A
This my controller
(function () {
"use strict"
angular
.module("myApp")
.controller("userCtrl",['$scope', '$state', 'userService', 'appSettings','md5','currentUser','$rootScope',
function ($scope, $state, userService, appSettings,md5,currentUser, $rootScope) {
$scope.login = function() {
$scope.loading = true;
if($scope.password != null){
var user ={
username:$scope.username,
password:md5.createHash($scope.password)
}
var getData = userService.login(user);
getData.then(function (response) {
console.log(response);
$scope.loading = false;
currentUser.setProfile(user.username, response.data.sessionId);
$state.go('videos');
}, function (response) {
console.log(response.data);
});
}else{
$scope.msg = "Password field is empty!"
}
}
}])
}());
This is my test codes
'use strict';
describe('userCtrl', function() {
beforeEach(module('myApp'));
var scope, userCtrl, apiService,q, deferred, currentUser;
describe('$scope.login', function(){
beforeEach(function(){
apiService = {
login: function () {
deferred = q.defer();
return deferred.promise;
};
};
});
beforeEach(inject(function($controller, $rootScope, $q, _currentUser_){
var user ={name:'ali',password:'password'};
scope = $rootScope.$new();
q = $q;
// The injector unwraps the underscores (_) from around the parameter names when matching
userCtrl = $controller('userCtrl', {
$scope:scope,
userService:apiService
});
//userService = _userService_;
currentUser = _currentUser_;
}));
it('should call user service login', function() {
spyOn(apiService, 'login').and.callThrough();
scope.login();
deferred.resolve(user);
expect(apiService.login).toHaveBeenCalled();
});
it('checks the password field', function() {
scope.login();
expect(scope.msg).toEqual('Password field is empty!');
});
});
});
And i am getting this error
enter image description here
If you have to test controller then use to spyon for service method and in case of service then use HttpBackend
describe('Testing a Controller that uses a Promise', function() {
var $scope;
var $q;
var deferred;
beforeEach(module('search'));
beforeEach(inject(function($controller, _$rootScope_, _$q_, searchService) {
$q = _$q_;
$scope = _$rootScope_.$new();
// We use the $q service to create a mock instance of defer
deferred = _$q_.defer();
// Use a Jasmine Spy to return the deferred promise
spyOn(searchService, 'search').and.returnValue(deferred.promise);
// Init the controller, passing our spy service instance
$controller('SearchController', {
$scope: $scope,
searchService: searchService
});
}));
it('should resolve promise', function() {
// Setup the data we wish to return for the .then function in the controller
deferred.resolve([{
id: 1
}, {
id: 2
}]);
// We have to call apply for this to work
$scope.$apply();
// Since we called apply, not we can perform our assertions
expect($scope.results).not.toBe(undefined);
expect($scope.error).toBe(undefined);
});
});
This for same using spyon for service method then use $appy method to make it work.
New to Jasmine tests for angular. I am trying to test if the controller I defined is defined or not to begin with but I am getting error saying Expected undefined to be defined.
Here is my main code:
// controller logic MatchController.js
(function () {
'use strict';
angular.module('app.match')
.controller('MatchController', MatchController);
MatchController.$inject = ['APP_CONFIG', '$authUser', '$http', '$rootScope', '$state', '$stateParams', 'SearchService', 'ConfirmMatchService', 'MusicOpsService', 'ContentOpsService', 'MatchstickService', 'MatchService', 'Restangular'];
function MatchController(APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams, searchService, confirmMatchService, musicOpsService, contentOpsService, matchstickService, matchService, Restangular) {
var vm = this;
.
.
.
}
})();
Here is the test file
// MatchController.spec.js
(function(){
'use strict';
describe('Match Controller Tests', function(){
var module, MatchTestController;
beforeEach(function() {
module = angular.module('app.match');
});
beforeEach(inject(function ($controller) {
MatchTestController = $controller('MatchController', {});
}));
describe("Match controller to be defined", function() {
it("should be created successfully", function () {
expect(MatchTestController).toBeDefined();
});
});
});
})();
I keep getting the error:
TypeError: 'undefined' is not a function (evaluating 'angular.controller('MatchController')')
undefined
at /Users/rgoti/match-ui/match-ui/public/src/app/match/match.controller.spec.js:16
at invoke (/Users/rgoti/match-ui/match-ui/public/bower_components/angular/angular.js:4219)
at workFn (/Users/rgoti/match-ui/match-ui/public/bower_components/angular-mocks/angular-mocks.js:2475)
Expected undefined to be defined.
at /Users/rgoti/match-ui/match-ui/public/src/app/match/match.controller.spec.js:22
Not sure what I am doing wrong here.
You should inject all the dependencies in the controller first before mocking it.
Try this:
// MatchController.spec.js
(function(){
'use strict';
describe('controller: MatchController', function(){
var module, MatchController, APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams, SearchService, ConfirmMatchService, MusicOpsService, ContentOpsService, MatchstickService, MatchService, Restangular;
beforeEach(function() {
module = angular.module('app.match');
});
beforeEach(inject(function ($controller, _APP_CONFIG_, _$authUser_, _$http_, _$rootScope_, _$state_, _$stateParams_, _SearchService_, _ConfirmMatchService_, _MusicOpsService_, _ContentOpsService_, _MatchstickService_, _MatchService_, _Restangular_) {
APP_CONFIG = _APP_CONFIG_;
$authUser = _$authUser_;
$http = _$http_;
$rootScope = _$rootScope_;
$state = _$state_;
$stateParams = _$stateParams_;
SearchService = _SearchService_;
ConfirmMatchService = _ConfirmMatchService_;
MusicOpsService = _MusicOpsService_;
ContentOpsService = _ContentOpsService_;
MatchstickService = _MatchstickService_;
MatchService = _MatchService_;
Restangular = _Restangular_;
MatchController = $controller('MatchController', {
APP_CONFIG: _APP_CONFIG_,
$authUser: _$authUser_,
$http: _$http_,
$rootScope: _$rootScope_,
$state: _$state_,
$stateParams: _$stateParams_,
SearchService: _SearchService_,
ConfirmMatchService: _ConfirmMatchService_,
MusicOpsService: _MusicOpsService_,
ContentOpsService: _ContentOpsService_,
MatchstickService: _MatchstickService_,
MatchService: _MatchService_,
Restangular: _Restangular_
});
}));
describe("Match controller to be defined", function() {
it("should be created successfully", function () {
expect(MatchController).toBeDefined();
});
});
});
})();
I'm trying to put some tests on a controller using ressources/promises. I had followed the article Mocking $resource and promises in AngularJS unit tests.
However I can't get a simple case to work as the queryDeferred object is undefined.
Error
PhantomJS 1.9.8 (Linux) OrdersModule API.Orders.query should query the API.Orders FAILED
TypeError: 'undefined' is not an object (evaluating 'queryDeferred.resolve')
at /mnt/data/projects/tcs_economat/frontend/static_src/test/unit/orderSpec.js:52
PhantomJS 1.9.8 (Linux): Executed 25 of 25 (1 FAILED) (0.235 secs / 0.223 secs)
Controller
"use strict";
angular.module('OrdersModule', ['services'])
.controller('OrdersControllers', ['$scope', 'API', function ($scope, API) {
$scope.orders = [];
API.Order.query().$promise.then(function (data) {
console.log(data);
});
}]
);
Test
"use strict";
describe('OrdersModule', function () {
var $q,
$rootScope,
$scope,
mockOrdersApiService,
queryDeferred,
mockOrdersResponse = [
{status: 'DRAFT'},
{status: 'DRAFT'}
];
beforeEach(module('tcsStoreApp'));
beforeEach(inject(function (_$q_, _$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
beforeEach(inject(function ($controller) {
$scope = $rootScope.$new();
mockOrdersApiService = {
query: function () {
queryDeferred = $q.defer();
return {$promise: queryDeferred.promise};
}
};
spyOn(mockOrdersApiService, 'query').andCallThrough();
$controller('OrdersControllers', {
'$scope': $scope,
'API.Orders': mockOrdersApiService
});
}));
describe('API.Orders.query', function () {
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
var $httpBackend = _$httpBackend_;
queryDeferred.resolve(mockOrdersResponse);
$rootScope.$apply();
$httpBackend.expectGET('/static/js/tcs.fr.json').respond({});
}));
it('should query the API.Orders', function () {
expect(mockOrdersApiService.query).toHaveBeenCalled();
});
});
});
Question
Is the mockOrdersApiService correctly declared?
Why is the queryDeferred.resolve undefined?
I am trying to write a unit test to test a simple factory that performs a http.get to retrieve a JSON file.
The factory is called within my controller.
Here's a plunker showing my http.get: http://plnkr.co/edit/xg9T5H1Kreo4lwxzRQem?p=preview
Ctrl:
app.controller('MainCtrl', function($scope, $http, factoryGetJSONFile) {
factoryGetJSONFile.getMyData(function(data) {
$scope.Addresses = data.Addresses.AddressList;
$scope.People = data.Names.People;
});
});
Factory:
app.factory('factoryGetJSONFile', function($http) {
return {
getMyData: function(done) {
$http.get('data.json')
.success(function(data) {
done(data);
})
.error(function(error) {
alert('An error occured whilst trying to retrieve your data');
});
}
}
});
Test:
// ---SPECS-------------------------
describe('with httpBackend', function () {
var app;
beforeEach(function () {
app = angular.mock.module('plunker')
});
describe('MyCtrl', function () {
var scope, ctrl, theService, httpMock;
beforeEach(inject(function ($controller, $rootScope, factoryGetJSONFile, $httpBackend) {
scope = $rootScope.$new(),
ctrl = $controller('MyCtrl', {
$scope: scope,
factoryGetJSONFile: theService,
$httpBackend: httpMock
});
}));
it("should make a GET call to data.json", function () {
console.log("********** SERVICE ***********");
httpMock.expectGET("data.json").respond("Response found!");
//expect(factoryGetJSONFile.getMyData()).toBeDefined();
httpMock.flush();
});
})
});
Error:
TypeError: 'undefined' is not an object (evaluating 'httpMock.expectGET')
You should assign $httpBackend to httpMock in beforeEach like this:
beforeEach(inject(function ($controller, $rootScope, factoryGetJSONFile, $httpBackend) {
httpMock = $httpBackend;
scope = $rootScope.$new();
ctrl = $controller('MyCtrl', {
$scope: scope,
factoryGetJSONFile: factoryGetJSONFile,
$httpBackend: httpMock
});
}));