ankitd ankitd - 1 month ago 19
AngularJS Question

unit test angular bootstrap modal service

I have created a common

ModalService
and this is used for two diferrnt type of dialogs.
CancelDialog
and
ErrorDialog
will be popped up as per parameter passed to service.

Why do we Unit Test when functionality is working fine??

i.e This will show an
ErrorDialog


ModalService.openModal('Analysis Error', 'I am Error Type', 'Error');


All is working fine but am stuck with Unit Test. Here is working PLUNKER.
Please help in covering Unit Test for this.

How to do Unit Test for
openErrorModal
&
openCancelModal
in below service.

ModalService

// common modal service
validationApp.service('ModalService',
function($uibModal) {

return {
openModal: openModal
};

function openErrorModal(title, message, callback) {
$uibModal.open({
templateUrl: 'ErrorDialog.html',
controller: 'ErrorDialogCtrl',
controllerAs: 'vm',
backdrop: 'static',
size: 'md',
resolve: {
message: function() {
return message;
},
title: function() {
return title;
},
callback: function() {
return callback;
}
}
});
}

function openCancelModal(title, message, callback) {
$uibModal.open({
templateUrl: 'CancelDialog.html',
controller: 'ErrorDialogCtrl',
controllerAs: 'vm',
backdrop: 'static',
size: 'md',
resolve: {
message: function() {
return message;
},
title: function() {
return title;
},
callback: function() {
return callback;
}
}
});
}

function openModal(title, message, modalType, callback) {
if (modalType === "Error") {
openErrorModal(title, message, callback);
} else {
openCancelModal(title, message, callback);
}
}
}
);


How to Unit Test
onOk
,
onContinue
&
onDiscard
in below controller.

DialogController

//controller fot dialog
validationApp.controller('ErrorDialogCtrl',
function($uibModalInstance, message, title, callback) {
alert('from controller');
var vm = this;
vm.message = message;
vm.onOk = onOk;
vm.onContinue = onContinue;
vm.onDiscard = onDiscard;
vm.callback = callback;
vm.title = title;

function onOk() {
$uibModalInstance.close();
}

function onContinue() {
$uibModalInstance.close();
}

function onDiscard() {
vm.callback();
$uibModalInstance.close();
}
});

Answer

You need to separately test service and controllers. For controllers, you need to test that methods of uibModalInstance are called when controller methods are called. You don't actually need to test that dialog closes, when close method is called. That is the task of those who implemented uibModal.

So here is the test for controller:

describe('ErrorDialogCtrl', function() {

    // inject the module of your controller
    beforeEach(module('app'));

    var $controller;

    beforeEach(inject(function(_$controller_){
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $controller = _$controller_;
    }));

    it('tests that close method is called on modal dialog', function() {
        var $uibModalInstance = {
            close: jasmine.createSpy('close')
        };

        var callback = function() {};
        var controller = $controller('PasswordController', { $uibModalInstance: $uibModalInstance, message: {}, callback: callback });

        controller.onOk();
        expect($uibModalInstance.close).toHaveBeenCalled();
    });
});

Here is the simply test for service:

describe('ModalService', function () {

    var $injector;
    var $uibModal;

    // inject the module of your controller
    beforeEach(module('app', function($provide) {
        $uibModal = {
            open: jasmine.createSpy('open')
        };

        $provide.value('$uibModal', $uibModal);
    }));

    beforeEach(inject(function (_$injector_) {
        $injector = _$injector_;
    }));

    it('tests that openErrorModal is called', function () {
        var modalService = $injector.get('ModalService');
        modalService.openModal(null, null, "Error");

        expect($uibModal.open).toHaveBeenCalledWith(jasmine.objectContaining({
            controller: "ErrorDialogCtrl"
        }));
    });
});
Comments