The app is working properly with my module. But building the following mock returns :
$global_vars is not defined
I imagine that I'm not injecting the module properly. What am I missing here?
describe('CalendarController', function() {
beforeEach(module("$global_vars"));
beforeEach(inject(function($rootScope, $controller, $location, $injector, $global_vars) {
var $httpBackend;
$httpBackend = $injector.get('$httpBackend');
return this.controller = $controller(CalendarController, {
$scope: this.scope,
$location: $location,
$global_vars: $global_vars
});
}));
return it("can be instantiated", function() {
return expect($global_vars).not.toBeNull();
});
});
note: this is a coffeescript translation to vanilla js
UPDATE
Ok so by doing this I get another, possibly better error?
Error: Unknown provider: $httpProvider <- $http <- $global_vars
.
describe 'CalendarController', ->
beforeEach module("$global_vars")
beforeEach module("GlobalService")
beforeEach inject ($rootScope, $controller, $location, $injector) ->
$injector = angular.injector [ '$global_vars' ]
$global_vars = $injector.get('$global_vars')
$global_vars = $injector.get('$global_vars')
#controller = $controller CalendarController, {$scope: #scope, $location: $location}
The bare bones of my backbone.js
angular.module("VarsService", []).factory "$global_vars", ["$http", '$location', ($http, $location) ->
global_vars.get_calendar = ->
console.log 'blam!'
Related
I'm writing unit tests for my project built on Angularjs with Karma-jasmine. I'm using x-editable library in my app.
I'm trying to unit test a controller which depends on the x-editable library.
But I'm facing the error below :
Error: [$injector:unpr] Unknown provider: editableThemesProvider <- edit ableThemes
I have already added the path of x-editable my in Karma config file :
files:[
......
{ pattern: '../../libs/angular/angular-xeditable/dist/js/xeditable.min.js', watched: false },
........
]
Below the spec file :
beforeEach(inject(function(_$controller_, $rootScope, $localStorage, _editableThemes_, _editableOptions_) {
localStorage = $localStorage;
$controller = _$controller_;
editThemes = _editableThemes_;
editOptions = _editableOptions_;
scope = $rootScope.$new();
leaderboardCtrl = $controller('LeaderboardCtrl', {
$scope: scope,
$modal : modal,
$q: q,
editableOptions: editOptions,
editableThemes: editThemes,
$localStorage: localStorage,
LeaderBoardService : leaderboardService
});
}));
And this is my controller file :
(function() {
'use strict';
angular
.module('app')
.controller('LeaderboardCtrl', leaderboardCtrl);
leaderboardCtrl.$inject = ['$scope', '$q', '$modal', '$localStorage', 'editableOptions', 'editableThemes', 'LeaderBoardService'];
function leaderboardCtrl ( $scope, $q, $modal, $localStorage, editableOptions, editableThemes, LeaderBoardService) {
var event_ID = $localStorage.currentEventId;
editableThemes.bs3.inputClass = 'input-sm';
editableThemes.bs3.buttonsClass = 'btn-sm';
editableOptions.theme = 'bs3';
What am I doing wrong? did i missed something?
describe('Controller:explorerCtrl', function() {
'use strict';
var explorerCtrl;
var explorerService;
var listService;
var scope;
var $httpBackend;
var aggregatedPods_;
var $state;
var $mdDialog;
var StateService;
var spy;
beforeEach(module(
'ui.router', explorer, kpi,
list));
beforeEach(inject(function(
_$controller_, _$httpBackend_, _$rootScope_, _explorerService_, _$state_,
_listService_) {
scope = _$rootScope_.$new();
listService = _listService_;
aggregatedPods_ = {};
explorerService = _explorerService_;
spy = jasmine.createSpy();
StateService = {go: spy};
$httpBackend = _$httpBackend_;
$state = _$state_;
explorerCtrl =
_$controller_('explorerCtrl', {$scope: scope, $state: StateService});
}));
});
Hi,
I am trying to write angular test cases for my separate module. Unfortunately, my list module above breaks down my test cases. I have common service listServices($mdDialog) and using directly in my list controller(list module). When I am trying to run my angular unit test then I got an error unknown $provider $mdDialogProvider <- $mdDialog <- listService .What should I do in this case ?
I already tried to inject $mdDialog into $inject function. Still got same error. Please correct me where I am doing wrong.
beforeEach(inject(function(
_$controller_, _$httpBackend_, _$rootScope_, _explorerService_, _$state_,
_listService_ _$mdDialog_);
I think you need to inject the $mdDialog using $provide and in your controller you need to inject $mdDialog like this:
beforeEach(function() {
module(function(_$provide_) {
_$provide_.service('$mdDialog', function() {});
});
});
beforeEach(inject(function(
_$controller_,
_$httpBackend_,
_$rootScope_,
_explorerService_,
_$state_,
_listService_,
_$mdDialog_) {
// ...
}));
I've been trying to get started with unit testing in angular with karma and jasmine, and i've been pulling my hair out trying to wrap my head around how to test controllers with dependencies. I tried mocking a spy with a jasmine spyObj and registering it in the beforeEach hook, but for some reason the spy isn't being recognized.
Here's the code:
angular.module('testModule', [])
.controller('TestController', [
'$scope',
'TestService',
function ($scope, TestService) {
$scope.data = TestService.load();
}])
.factory('TestService', function () {
return {
load: function(){
return "foo";
}
}
});
and here's the test
describe('TestController', function() {
var $controller, $scope, TestService;
beforeEach(module('testModule'), function($provide){
TestService = jasmine.createSpyObj("TestService", ["load"]);
TestService.load.andReturn("bar");
$provide.value("TestService", TestService)
});
beforeEach(inject(function(_$controller_, $rootScope, _TestService_) {
$scope = $rootScope.$new();
TestService = _TestService_;
$controller = _$controller_('TestController', {
$scope: $scope,
TestService: TestService
});
}));
it('should set $scope.data to bar when TestService.load is called', function() {
expect(TestService.load).toHaveBeenCalled();
expect($scope.data).toEqual("bar");
}); });
Both assertions in the test fail.
I get 'Error: Expected a spy, but got Function' when i call expect(TestService.load).toHaveBeenCalled();
and if I call expect($scope.data).toEqual("bar"), I get Expected 'foo' to equal 'bar'. "Foo" is coming from the actual service, not the spy object.
Thanks for your help.
Instead of jasmine.createSpyObj, it will be easier to use the existing service that the $injector provides and then just mock the single method. You can achieve this with spyOn instead:
describe('TestController', function() {
var $controller, $scope, TestService;
beforeEach(module('testModule'));
beforeEach(inject(function(_$controller_, $rootScope, _TestService_) {
$scope = $rootScope.$new();
TestService = _TestService_;
spyOn(TestService, 'load').and.returnValue('bar');
$controller = _$controller_('TestController', {
$scope: $scope,
TestService: TestService
});
}));
it('should set $scope.data to bar when TestService.load is called', function() {
expect(TestService.load).toHaveBeenCalled();
expect($scope.data).toEqual("bar");
});
});
In your beforeEach you are injecting in _TestService_ and then overwriting the one you declared in the previous beforeEach via:
TestService = _TestService_;
Remove that code and your test should succeed.
Also there is no need to do this:
$provide.value("TestService", TestService)
Basically you're trying to use Angular's dependency injection when you're manually injecting things which is unnecessary.
Here is what I am doing :
controller.js
var app = angular.module('app', [ 'angularFileUpload' ]);
app.controller('MyCtrl', [ '$scope', '$http', '$timeout', '$upload',
function($scope, $http, $timeout, $upload) {
$scope.something;
$scope.deleteFile = function(fileId) {
$http({
method : 'DELETE',
url : "http://xxx.xxx.xx.xx:8080/fileId
}).success(function(response) {
scope.something=response;
console.log(response);
});
});
controllerspec.js
ddescribe("MyCtrl test cases ",function(){
var scope , controller ,httpBackend;
beforeEach(angular.mock.module('app'));
beforeEach(angular.mock.inject(function($rootScope,$controller,$http, $timeout, $upload){
scope = $rootScope.$new();
httpBackend = $http;
$controller('MyCtrl',{
$scope:scope,
$http:httpBackend,
$timeout:$timeout,
$upload:$upload
});
}));
it("should delete selected file ",function(){
/*HERE*/ httpBackend.when('DELETE','http://xxx.xxx.xx.xx:8080/1').respond
({
"deleted"
});
httpBackend.flush();
scope.deleteFile(1);
expect(scope.something).toBeDefined();
});
I get TypeError: Undefined is not a function at line "HERE".
What am I missing ?
You have error in your code because of following piece of code
Instead of
beforeEach(angular.mock.inject(function($rootScope,$controller,$http, $timeout, $upload){
scope = $rootScope.$new();
httpBackend = $http;
$controller('MyCtrl',{
$scope:scope,
$http:httpBackend,
$timeout:$timeout,
$upload:$upload
});
use
beforeEach(angular.mock.inject(function($rootScope,$controller,$httpBackend, $timeout, $upload){
scope = $rootScope.$new();
httpBackend = $httpBackend;
$controller('MyCtrl',{
$scope:scope,
$timeout:$timeout,
$upload:$upload
});
$httpBackend is used for mocking http requests, no need to inject it inside controller, instead you may inject $http service. Also you had error as you didn't injected httpBackend service and were trying to use its function that why you got undefined error.
I'm getting this error when trying to test a controller in Karma:
Error: [$injector:unpr] http://errors.angularjs.org/1.2.14/$injector/unp
r?p0=%24elementProvider%20%3C-%20%24element
at c:/js/libs/angular/angular1.2.14/angular.min.js:32
at c (c:/js/libs/angular/angular1.2.14/angular.min.js:30)
at c:/js/libs/angular/angular1.2.14/angular.min.js:32
at c (c:/js/libs/angular/angular1.2.14/angular.min.js:30)
at d (c:/js/libs/angular/angular1.2.14/angular.min.js:30)
at c:/js/libs/angular/angular1.2.14/angular.min.js:31
at c:/js/libs/angular/angular1.2.14/angular.min.js:63
at c:/tests/unit/widget_tests/myTest.test.js:13
at d (c:/js/libs/angular/angular1.2.14/angular.min.js:30)
at workFn (c:/js/libs/angular/angular1.2.14/angular-mocks.js:2160)
I'm including all the angular files in karma.conf.js and compiling the controller like so:
var $scope, $http, $translate;
beforeEach(module('myApp.services'));
beforeEach(module('myApp.directives'));
beforeEach(inject(function ($rootScope, $controller, _$httpBackend_) {
$scope = $rootScope.$new();
$controller('myController', {$scope : $scope});
}));
describe('Initialization :', function(){
it('Should ', function() {
})
})
})
I needed to inject the $element into the controller, though compiling the full directive is another option.
$controller('myController', {$scope : $scope, $element :$('<div></div>')});
Posting this as the duplicate question is missing an example.
Your $scope variable is undefined so far.
By the way, the following should work:
var $scope, $httpBackend;
beforeEach(function() {
module('myApp', 'myApp.services', 'myApp.directives'));
inject(function ($rootScope, $controller, _$httpBackend_) {
$scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$controller('myController', {$scope : $scope});
}));
});
describe('Initialization :', function(){
it('Should ', function() {
})
});