I am new to unit test.
Please help me to write test case code for following code:
$scope.convertToInt = function (str) {
if (!isNumberEmpty(str) && !isNaN(str)) {
return parseInt(str, 10);
}
return "";
}
I have tried like this, but not able to do.
describe('ConfigurationTestController', function() {
beforeEach(module('usp.configuration'));
describe('ConfigurationController', function () {
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller('ConfigurationController', {
'$scope': scope
});
}));
});
});
Please tell me how can I write.......
you need to modify your code a bit. you don't need to use describe twice in your test case.
(function() {
"use strict";
describe("test suite for Configuration test controller", function() {
var scope = null;
beforeEach(module("usp.configuration"));
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
$controller("ConfigurationController", {
$scope: scope
});
}));
it("should convert to int", function() {
expect(scope.convertToInt("2")).to.equal(2);
});
it("should return empty string", function() {
expect(scope.convertToInt("asd")).to.equal("");
});
});
}());
Related
I called one $mdDialog inside a function. I want to unit-test $mdDialog ok and cancel cases.
The below is my controller code (app.controller.js).
(function () {
'use strict';
app.controller('AppCtrl', AppCtrl);
AppCtrl.$inject = ['$scope', '$mdDialog'];
function AppCtrl($scope, $mdDialog) {
$scope.saveEntry = function (ev) {
var confirm = $mdDialog.prompt()
.title('Save Entry')
.textContent('If you want, you can add a description to explain what you changed.')
.placeholder('Version Description')
.ariaLabel('Version Description')
.initialValue('')
.targetEvent(ev)
.ok('Save')
.cancel('Cancel');
$mdDialog.show(confirm).then(function (result) {
$scope.status = true;
}, function () {
$scope.status = false;
});
};
}
})();
The following is the spec code (app.controller.spec.js) :
describe('Unit test AppController: mdDialog', function () {
var $controller, $mdDialog;
beforeEach(function () {
module('App');
inject(function (_$controller_, _$mdDialog_) {
$controller = _$controller_;
$mdDialog = _$mdDialog_;
});
});
it(': Opened', function () {
var $scope = {};
var controller = $controller('AppCtrl', { $scope: $scope });
var $mdDialogOpened = false;
$mdDialog.show = jasmine.createSpy().and.callFake(function () {
$mdDialogOpened = true;
});
$scope.saveEntry();
$scope.$digest();
expect($mdDialog.show).toHaveBeenCalled;
expect($mdDialogOpened).toBe.true;
});
});
when I running the above code I'm getting the following error:
TypeError: Cannot read property 'then' of undefined
I referred this GitHub issue https://github.com/angular/material/issues/1482. But I'm not getting solution for my problem
Thanks in advance
The problem is that you are injecting one version of $mdDialog, and trying to test on another one.
You could try something like this:
describe('Unit test AppController: mdDialog', function () {
var ctrl, mdDialog, scope;
beforeEach(function () {
module('App');
inject(function ($rootScope, $controller, $mdDialog) {
scope = $rootScope.$new();
mdDialog = $mdDialog; //keep the reference, for later testing.
spyOn(mdDialog, 'show');
mdDialog.show.and.callFake(function () {
return {
then: function (callBack) {
callBack(true); //return the value to be assigned.
}
}
});
ctrl = $controller('AppCtrl',{$scope:scope, $mdDialog:mdDialog}); //Inject the dependency
});
});
it(': Opened', function () {
scope.saveEntry(); //exercise the method.
scope.$digest();
expect(mdDialog.show).toHaveBeenCalled();
expect(scope.status).toBe(true);
});
});
Something very similar should work.
hope this help.
I am trying to get/set "testModel.number" in my unit test but I can't seem to get it. When I run the test I get this error message:
Error: [$injector:unpr] Unknown provider: testModelProvider <- testModel
Here is the controller:
angular.module("TestApp", [])
.controller("IndexController", function ($scope, testModel) {
$scope.name = "test";
testModel = {
number: 0
}
if (testModel.number === 1) {
$scope.name = "test1";
} else {
$scope.name = "test2";
}
});
Here is the unit test:
describe('IndexController', function () {
var scope, createController;
beforeEach(module("TestApp"));
beforeEach(inject(function ($rootScope, $controller, testModel) {
scope = $rootScope.$new();
createController = function () {
return $controller('IndexController', {
'$scope': scope,
'testModel': testModel
})
}
}));
it('example test', function () {
var controller = createController();
testModel.number = 1;
expect(scope.name).toBe('test1');
});
});
I'm fairly new to unit testing so any suggestions would be great! Thanks in advance!
I think you need to pass the testModel object to the method creating the controller. Jasmine does not know how to inject custom providers.
describe('IndexController', function () {
var scope, createController;
beforeEach(module("TestApp"));
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
createController = function (testModel) {
return $controller('IndexController', {
'$scope': scope,
'testModel': testModel
})
}
}));
it('example test', function () {
var testModel = { number: 1 };
var controller = createController(testModel);
expect(scope.name).toBe('test1');
});
});
If you will have multiple tests that will need the testModel object, you can also define it at a global level as follows:
describe('IndexController', function () {
var scope, createController;
var testModel = { number: 1 };
beforeEach(module("TestApp"));
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
createController = function () {
return $controller('IndexController', {
'$scope': scope,
'testModel': testModel
})
}
}));
it('example test', function () {
var controller = createController();
expect(scope.name).toBe('test1');
});
});
I'm trying to test if a $scope method has been called
my controller :
(function () {
var app = angular.module('productsController',[]);
app.controller('AddProductController', ['$scope',function ($scope) {
$scope.test = function(){
return true;
};
$scope.test();
}]);
})();
and my test :
describe("Products Controller", function () {
beforeEach(function () {
module('productsController');
});
beforeEach(function () {
var createController, scope, rootScope;
});
describe('AddProductController', function () {
beforeEach(function () {
inject(function ($controller, _$rootScope_) {
rootScope = _$rootScope_;
scope = _$rootScope_.$new();
createController = function () {
return $controller("AddProductController", {
$scope: scope,
});
};
});
});
it('should call test', function(){
spyOn(scope, 'test');
createController();
scope.$apply()
expect(scope.test).toHaveBeenCalled();
})
});
});
but I got this error:
Error: test() method does not exist
$scope.test exists any when I run the app in a browser the method is been called, but if falis whne testing, any clues?
May be there is some problem in the ordering, Could you try and check if the below works?
describe('AddProductController', function() {
var createController, scope, rootScope;
beforeEach(function() {
inject(function($controller, _$rootScope_) {
rootScope = _$rootScope_;
scope = _$rootScope_.$new();
createController = function() {
return $controller("AddProductController", {
$scope: scope,
});
};
});
});
it('should call test', function() {
createController(); // To create function test in the scope
spyOn(scope, 'test');
createController(); // To execute test after spy is added.
expect(scope.test).toHaveBeenCalled();
})
});
I have the following controller:
(function () {
"use strict";
angular.module('usp.configuration').controller('ConfigurationController', ConfigurationController);
ConfigurationController.$inject = ['$scope', '$rootScope', '$routeParams', 'configurationService'];
function ConfigurationController($scope, $rootScope, $routeParams, configurationService) {
//Get Master Gas List
configurationService.getMasterGasList().then(function (response) {
$scope.masterGasList = response.data.data;
});
$scope.convertToInt = function (str) {
if (!isNumberEmpty(str) && !isNaN(str)) {
return parseInt(str, 10);
}
return "";
}
$scope.convertToString = function (num) {
if (!isNumberEmpty(num) && !isNaN(num)) {
return num + "";
}
return "";
}
}
}());
And below is the test case for the controller:
describe("test suite for Configuration test controller", function() {
var scope = null;
var configurationService;
beforeEach(module("usp.configuration"));
beforeEach(inject(function($rootScope, $controller, _configurationService_) {
// Services
// _'s are automatically unwrapped
configurationService = _configurationService_;
// Controller Setup
scope = $rootScope.$new();
$controller("ConfigurationController", {
$scope: scope,
configurationService : configurationService
});
}));
it("should convert to int", function() {
expect(scope.convertToInt("2")).toEqual(2);
});
it("should return empty string", function() {
expect(scope.convertToInt("asd")).toEqual("");
});
});
I don't want to call that service while I am running the test case.
I am new to unit testing, I don't know how can I do this.
Please help me to do this?
You need to mock the dependencies with $provide
beforeEach(function () {
configurationServiceMock = {
getSomething: function () {
return 'mockReturnValue';
}
};
module(function ($provide) {
$provide.value('configurationService', configurationServiceMock);
});
});
see: Injecting a mock into an AngularJS service
Solution for your needs:
var configurationServiceMock = {
getMasterGasList: function () {
return {
then: function(callback) {}
};
}
};
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller('ConfigurationController', {
'$scope': scope,
'configurationService': configurationServiceMock
});
}));
So I am trying to learn how to unit test with Jasmine with Angular. I have got a number of unit tests working but this one has stumped me. I took out the alerts array in my test you can make it any array.. But how to mock this and getting this to work has really stumped me. I would think that the object would exist.
(function () {
var app = angular.module("TabDirectives", ["Communication"]);
app.directive("sentAlerts", ["DirectiveProvider", "DataProvider", function (DirectiveProvider, DataProvider) {
var dir = DirectiveProvider("SentAlerts");
dir.controller = function () {
var ctrl = this;
DataProvider("AlertsByDate").then(function (Result) {
ctrl.AlertList = Result.data;
});
};
dir.controllerAs = "Alerts"
return dir;
}]);
})()
I have a test that looks like
describe("Tab Directive Unit Tests", function () {
var controller;
describe("Tab Directive Default Values", function () {
beforeEach(inject(function ($rootScope, $compile) {
element = angular.element("<sent-alerts></sent-alerts>");
$compile(element)($rootScope.$new());
$rootScope.$digest();
controller = element.controller;
}));
it("Ctrl should be this", function () {
expect(controller.ctrl).toBe(controller.this);
});
it("AlertList should have Alerts", function () {
expect(controller.ctrl.AlertList).toBe(alerts);
});
});
});
The error I'm getting looks like
TypeError: Cannot read property 'AlertList' of undefined
You have to initialize and inject your controller as well. Something like this:
var $controller;
var $rootScope;
var scope;
var controller;
beforeEach(inject(function (_$controller_, _$rootScope_) {
$controller = _$controller_;
$rootScope = _$rootScope_;
scope = $rootScope.$new();
controller = $controller('ScopeController', { '$scope': scope });
}));