How to unit test a modal in my case - angularjs

I am trying to test my modal in my script. but getting an error like
Unexpected request: GET modal/view.html. Here are my codes:
describe('test controller', function () {
var myCtrl, scope, rootScope, $httpBackend;
beforeEach(module('myApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_) {
rootScope = _$rootScope_;
scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_:
myCtrl = _$controller_('myCtrl', {
$scope: scope
});
}));
describe('test', function() {
it('it should load modal' , function() {
scope.loadModal();
//some http request tests
$httpBackend.flush();
});
});
});
controller
$scope.loadModal = function() {
//some http request codes…
$scope.modal = $modal({
template: 'modal/view.html',
scope: $scope
});
};
Getting error: Unexpected request: GET modal/view.html
modal/view.html is from the template params inside the modal
I am not sure how to patch this error in my case. Can anyone help me about it? Thanks a lot!

Related

Angularjs Jasmine unit testing a controller : $scope and ionicPopupProvider is undefined

I'm trying to test my simple controller but seems like nothing is working.
the controller:
userCtrlMod.controller('resetCtrl',
['$scope', '$ionicPopup', '$timeout','resetPwd',
function($scope, $ionicPopup, $timeout, resetPwd){
$scope.reset = function(){
$scope.resetPopUp = $ionicPopup.show({
templateUrl:'././templates/popup/reset.html',
scope: $scope
});
}}]);
my test file :
describe("resetCtrl", function () {
var $myScope, $myController, timeout;
beforeEach(module('dbooks.userCtrl'));
beforeEach(inject(function(
_$controller_,
_$rootScope_,
_$timeout_,
$ionicPopup
){
$myController = _$controller_;
$myScope = _$rootScope_;
$myController = $controller('resetCtrl' , {
$scope: $myScope,
$resetPopUp : $ionicPopup
});
}));
it("should have a $scope variable", function() {
//console.log($myScope);
expect($myScope).toBeDefined();
});});
I googled it but i could'nt find any solution, please someone tell me what I'm doing wrong.
the errors :
Uncaught Error: [$injector:unpr] Unknown provider: $ionicPopupProvider <- $ionicPopup
Uncaught Expected undefined to be defined.
at Object.
You don't provide all required dependencies when creating controller in test. You have to provide all dependencies required by the controller:
describe("resetCtrl", function () {
var $myScope, $myController, timeout;
beforeEach(module('dbooks.userCtrl'));
beforeEach(inject(function(
_$controller_,
_$rootScope_,
_$timeout_,
$ionicPopup
){
$myController = _$controller_;
$myScope = _$rootScope_;
var resetPwd = {
someResetmethod: jasmine.createSpy('rese')
};
$myController = $controller('resetCtrl' , {
$scope: $myScope,
$ionicPopup: $ionicPopup,
$timeout: _$timeout_,
resetPwd: resetPwd
});
}));
it("should have a $scope variable", function() {
//console.log($myScope);
expect($myScope).toBeDefined();
});
}
Please note that you can inject mocked objects as dependencies - in above code instead of original resetPwd mocked object with spy as method is injected. The important thing is that you have to provide all dependencies used by your controller and if you inject mocked objects those object of course have to include required methods and properties.
Please try this.
$myScope =__$rootScope_.$new();

Should Angular Service Execute In Unit Test

I am trying to integrate Karma and Jasmine in to my project.
I have started off with a very basic test to ensure my controller is defined and a $scope variable equals a string - which pass as expected.
My controller, also calls a service which performed a $http.get, when running my test, without any mention of a service, i get the error:
Error: Unexpected request: GET /my/endpoint/
No more request expected
Controller:
define(['module'], function (module) {
'use strict';
var MyController = function ($scope, MyService) {
$scope.testScope = 'karma is working!';
MyService.getData().then(function (data) {
$scope.result = data.hour
});
};
module.exports = ['$scope', 'MyService', MyController ];
});
Test:
define(['require', 'angular-mocks'], function (require) {
'use strict';
var angular = require('angular');
describe("<- MyController Spec ->", function () {
var controller, scope;
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function (_$controller_, _$rootScope_) {
scope = _$rootScope_.$new();
controller = _$controller_('MyController', {$scope: scope});
scope.$apply();
}));
it('should verify that the controller exists ', function() {
expect(controller).toBeDefined();
});
it('should have testScope scope equaling *karma is working*', function() {
expect(scope.testScope ).toEqual('karma is working!');
});
});
});
Are the above errors expected?
UPDATE from response below:
define(['require', 'angular-mocks'], function (require) {
'use strict';
var angular = require('angular');
describe("<- MyController Spec ->", function () {
var controller, scope, $httpBackend, myService;
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_, _myService_) {
scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_;
$httpBackend.expectGET("/my/endpoint");
controller = _$controller_('MyController', {$scope: scope});
scope.$apply();
}));
it('should verify that the controller exists ', function() {
expect(controller).toBeDefined();
});
it('should have testScope scope equaling *karma is working*', function() {
expect(scope.testScope ).toEqual('karma is working!');
});
});
});
Using Angular Mocks you will always get an error if there is an unexpected or incorrect http request attempted -- even for templates. In your case there are two ways to handle this for testing:
use $httpBackend
$httpBackend was designed for testing http requests without actually hitting the wire. In your test, simply add
$httpBackend.expectGET("/my/endpoint");
before you initialize the controller.
Mock the service
The service itself is making the http request, so you can mock the service instead. Services will be injected automatically as usual, but you can explicitly injection whatever you want:
controller = _$controller_('MyController', {$scope: scope,
MyService: {getData: () => ({then: () => {}}) });
This injects an object that has a getData function which returns an object with .then function. Of course this doesn't come close to implementing what you are trying to do, but it is another way to perform the test.
Both of the above approaches are valid. It depends on what you are testing and what you are trying to accomplish with the testing.

Injecting custom factory in jasmine test

I tried to inject a factory to my controller in jasmine test like in
Unit testing AngularJS factories that have dependencies
When I $provide a factory in the test, I would expect the controller to use the provided factory. But the console.log still prints 'real value'. I don't get it.
var app = angular.module('mod', []);
app.factory('factoryA', [
function () {
return "real value";
}
]);
app.controller('myController', ['factoryA',
function (factoryA) {
console.log(factoryA);
}
]);
describe("test", function() {
var $scope, $controller, $httpBackend;
var app;
beforeEach(function() {
module(function($provide) {
$provide.factory('factoryA', function () { return "fake value"; });
});
app = module("mod");
inject(function (_$controller_, _$httpBackend_, $rootScope) {
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
$controller = _$controller_;
});
});
it("works", function() {
$controller("myController", { '$scope': $scope });
});
});
You would need to get the $provider from the module mod so pass module name as first argument so that it overrides the factoryA definition that was created originally. Or load the module - module("mod") - before setting up mock.
module('mod', function($provide) {
$provide.factory('factoryA', function () { return "fake value"; });
});
Another way it to create mocks and pass it to the controller creation.
describe("test", function() {
var $scope, $controller, $httpBackend;
var app, factoryA;
beforeEach(function() {
module(mod);
inject(function (_$controller_, _$httpBackend_, $rootScope) {
//...Your code
//Mock factory
factoryA = jasmine.createSpy('factoryA');
factoryA.and.returnValue("fake value");
});
});
it("works", function() {
//Pass the mock factory
$controller("myController", { '$scope': $scope, factoryA:factoryA });
});
});

undefined controller in jasmine unit test

I am using karma via gulp-karma but getting the following error:
Error: [ng:areq] Argument 'adminPagesCtrl' is not a function, got
undefined
Here is my spec file:
describe('adminPagesCtrl', function() {
var $rootScope,
controller;
beforeEach(function() {
angular.module('jhApp')
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.html5Mode(true);
}]);
});
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller;
controller('adminPagesCtrl', {$scope: scope});
}));
it('does a thing', function() {
expect(true).toBe(true);
});
});
I have checked the browser window that karma opens up and can see all the files loaded. Application is working fine. Not sure what else to try?
This is now working:
describe('adminPagesCtrl', function() {
var $rootScope,
controller;
beforeEach(function() {
module('jhApp')
});
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller;
controller('adminPagesCtrl', {$scope: scope});
}));
it('does a thing', function() {
expect(true).toBe(true);
});
});

Jasmine Testing Angular Controller Method

So I have my blank tests passing with this setup.
describe('loginController', function() {
var scope, createController;
beforeEach(module('souply'));
beforeEach(inject(function ($rootScope, $controller, _$location_) {
$location = _$location_;
scope = $rootScope.$new();
createController = function() {
return $controller('loginController', {
'$scope': scope
});
};
}));
And here are the tests...
describe('processGoogleLogin', function(){
describe('successful', function(){
beforeEach(function() {
});
it('should connect to google plus', function () {
expect(true).toBe(true);
});
This one passes no problem.
QUESTION: How can I test a method on the login controller?
Here is the method I want to test on the login controller:
$scope.processGoogleLogin = function(){
console.log('process login was clicked');
window.location.replace('/#/dashboard');
};
The test I have so far is:
it('should sign you into the dashboard', function () {
scope.processGoogleLogin();
//$controller.processGoogleLogin();
//expect(window.location).toBe('/#/dashboard');
});
This test throws an error of:
'undefined' is not a function (evaluating 'scope.processGoogleLogin()')
This needed this line.
var ctrl = $controllerConstructor('myController', {$scope: scope, myResolve: {}, state: state});

Resources