angular.module('app').controller('ConvertController', ['$rootScope', '$scope', '$http', '$state', 'toaster', 'StorageManager', function($rootScope, $scope, $http, $state, toaster, StorageManager) {
$scope.authError = null;
$scope.init = function() {
var _authManager = window.client.getAuthManager();
};
$scope.init();
$scope.refreshDataForList = function() {
$scope.list = userlist.get();
};
$scope.searchConversation = function() {
var data = {
searchText: $scope.searchText
};
};
$scope.onchange = function(presence) {
console.log("IN CONTROLLER");
};
}])
I am using karma-jasmine to test my angular app. But while doing testing I am facing problem to access getAuthManager(). It gives error "cannot read getAuthManager() of undefined". However I have included all the files in proper order.
Related
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!
New to Jasmine, I am trying to instantiate my controller which has a list of dependencies (mainly the services I have written) and all the different ways I';ve tried haven't been right.
Here is my controller:
(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;
vm.greeting = '';
.
.
)();
Here is my test
(function(){
'use strict';
describe('app module', function() {
var MatchController;
//beforeEach(module('app.match'));
beforeEach(function($provide) {
module = angular.module('app.match');
$provide.service('SearchService', function(){
});
});
beforeEach(module('app.config'));
beforeEach(module('auth'));
beforeEach(inject(function($controller, APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams) {
MatchController = $controller('MatchController', {'APP_CONFIG':APP_CONFIG, '$authUser':$authUser, '$http':$http, '$rootScope':$rootScope, '$state':$state, '$stateParams':$stateParams, '$provide':$provide});
}));
describe("Match controller", function() {
it("should be created successfully", function() {
expect(MatchController).toBeDefined();
});
});
});
})();
Running test the above way gives me the following error:
TypeError: 'undefined' is not a function (evaluating '$provide.service('SearchService', function(){
})')
Try injecting the SearchService like this instead of using beforeEach.
describe('app module', function() {
var MatchController, SearchService;
beforeEach(module('app.match'));
beforeEach(module('app.config'));
beforeEach(module('auth'));
beforeEach(inject(function($controller, APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams, _SearchService_) {
SearchService = _SearchService_;
MatchController = $controller('MatchController', {
'APP_CONFIG':APP_CONFIG,
'$authUser':$authUser,
'$http':$http,
'$rootScope':$rootScope,
'$state':$state,
'$stateParams':$stateParams,
'$provide':$provide,
'SearchService': _SearchService_
});
}));
describe("Match controller", function() {
it("should be created successfully", function() {
expect(MatchController).toBeDefined();
});
});
});
})();
Similarly, you'll have to inject other services as well that your controller is relying on.
The issue is that I can't seem to send information from Controller 1 to Controller 2... I have my service that sets/gets data but it isn't working. The actual error that I'm getting is that Controller 1's dataService.getData is not a function... when it works elsewhere.
Service 1 (in its own file)
app.service('dataService', function() {
var data, queried;
return {
setData: function(queryData) {
this.data = queryData;
this.queried = false;
},
getData: function() {
this.queried = true;
return this.data;
}
};
});
Controller 1 (sending information)
app.controller('MyCtrl', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller 2 (getting information)
app.controller('MyCtrl2', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);
You didn't injected service dataService inside your MyCtrl & MyCtrl2, ensure dependency should be injected before using it.
Controller
app.controller('MyCtrl', ['$scope', '$location', '$state','dataService', //<-added dependency here
function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller2
app.controller('MyCtrl2', ['$scope', '$location', '$state','dataService',//<-added dependency here
function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);
I'm running a tutorial however they are using a version of AngularJS before 1.3.8.
What am I missing with my code so this data service can be injected?
They are using the following code to inject a service into a controller:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function () {
return { message: "I'm data from a service" };
});
function FirstCtrl($scope, Data) {
$scope.data = Data;
}
function SecondCtrl($scope, Data) {
$scope.data = Data;
}
Here is my code I am trying to alter so it works:
var myApp = angular.module('app', []);
myApp.factory('Data', function(){
return {message:"Data from service"}
});
angular.module('app', Data)
.controller('FirstController', ['$scope', function($scope) {
$scope.data = Data;
}])
.controller('SecondController', ['$scope', function($scope) {
$scope.data = {message: "panel"};
}]);
You must inject Data in the controller # .controller('FirstController', ['$scope', 'Data', function($scope, Data) { not list as module dependency # angular.module('app', Data). See the official DI documentation for more details and other options.
angular.module('app')
.controller('FirstController', ['$scope', 'Data', function($scope, Data) {
$scope.data = Data;
}])
.controller('SecondController', ['$scope','Data', function($scope, Data) {
$scope.data = {message: "panel"};
}]);
When you fetch a already created module you get by using angular.module('app'). You shouldn't be trying to inject the Data factory into the module but instead into the controller.
angular.module('app')
.controller('FirstController', ['$scope', 'Data', function($scope, Data) {
$scope.data = Data;
}])
.controller('SecondController', ['$scope', 'Data', function($scope, Data) {
$scope.data = {message: "panel"};
}]);
Use this:
angular.module('app')
.controller('FirstController', ['$scope', function($scope, Data) {
$scope.data = Data;
}])
.controller('SecondController', ['$scope', function($scope, Data) {
$scope.data = {message: "panel"};
}]);
My service is:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$state', '$cookies', '$base64', function($http, $q, $rootScope, $state, $cookies, $base64) {
var user;
user = {};
this.logout = function() {
user = {};
delete $cookies.userAccessKey;
return $state.transitionTo('login');
};
}
]);
I want to write a unit test to make sure that the $cookies.userAccessKey was deleted. How can I do this? While I'm at it, how can I ensure that user was set to empty?
To check if user is null, just add a public getter or checker :
myApp.service('userService', [
'$http', '$q', '$rootScope', '$state', '$cookies', '$base64', function($http, $q, $rootScope, $state, $cookies, $base64) {
var user;
this.user = {}; // or a method this.isLoggedIn() for more security
this.logout = function() {
this.user = {};
delete $cookies.userAccessKey;
return $state.transitionTo('login');
};
}
]);
Then, in your tests :
describe('logout', function(){
beforeEach(function(){
userService.login(); //relog before each test
});
it('should remove the userAccessKey from cookie', function() {
userService.logout();
inject(function($cookies) {
expect(cookies.userAccessKey).toBeUndefined();
});
});
it('should reset user object', function() {
userService.logout();
expect(userService.user).toEqual({});
});
});
});