如何对ui-bootsrap $ uibModal实例的结果进行单元测试?

时间:2017-03-29 20:36:56

标签: angularjs unit-testing jasmine angular-ui-bootstrap angular-mock

我有一个调用$ uibModal.open的控制器来弹出一个ui-bootstrap模式。控制器如下所示:

(function () {
    'use strict';

    angular
        .module('app')
        .controller('MyCtrl', myCtrl);

    function myCtrl($uibModal) {
        var vm = this;
        vm.showModal = showModal;

        vm.results = [];

        function showModal() {
            var modalInstance = $uibModal.open({
                templateUrl: '/mymodal.html',
                controller: 'ModalCtrl ',
                controllerAs: 'modalCtrl',
            });

            modalInstance.result.then(function (myResult) {
            // I want to test that my code here  gets called and behaves as   expected. shortened for brevity
                vm.results.push(myResult);
            });
        }
    }
})();

我已经成功测试了使用正确的配置选项打开模态。但是我想测试模态的结果,因为当发生这种情况时会执行某些逻辑,但我似乎无法弄清楚如何将其挂钩到结果中或者让它甚至在我的测试中执行

省略了一些设置代码的测试

(function() {
    'use strict';

    describe('myPageWithModal', function() {

        //mock edit modal
        var mockModalInstance = {
            result: {
                then: function(confirmCallback, cancelCallback) {
                    // Store the callbacks for later when the user clicks
                    // on the OK or Cancel button of the dialog
                    this.confirmCallBack = confirmCallback;
                    this.cancelCallback = cancelCallback;
                }
            },
            close: function( item ) {
                // The user clicked OK on the modal dialog, call the stored
                // confirm callback with the selected item
                this.result.confirmCallBack( item );
            },
            dismiss: function( type ) {
                // The user clicked cancel on the modal dialog, call
                // the stored cancel callback
                this.result.cancelCallback( type );
            }
        }

        var mockModalOptions = {
            controller: 'ModalCtrl ',
            controllerAs: 'modalCtrl',
            templateUrl: '/mymodal.html',
        }


        describe('myModal', function() {
            var actualModalOptions;

            beforeEach(function() {
                ctrl = //omitted

                //set up a spy to listen for when modal dialogs are opened and return our mock modal
                spyOn($uibModal, 'open').and.callFake(function(options) {
                    actualModalOptions = options;
                    return mockModalInstance;
                });
            });

            it('should open edit modal with options', function() {
                ctrl.showModal();

                expect($uibModal.open).toHaveBeenCalledWith(mockModalOptions);
            });


            it('should close modal and execute the modalInstance.result logic',     function() {

            });
        });
    });
})();

1 个答案:

答案 0 :(得分:3)

考虑到$uibModal.open在当前规范中被模拟为返回mockModalInstancemockModalInstance应该为每个使用它的规范进行新定义,而mockModalInstance.result应该是一个承诺:

var modalResult = {};
var mockModalInstance = { result: $q.resolve(modalResult) };
spyOn(mockModalInstance.result, 'then').and.callThrough();
spyOn($uibModal, 'open').and.returnValue(mockModalInstance);

ctrl.showModal();
$rootScope.$digest();

expect(mockModalInstance.result.then).toHaveBeenCalledWith(jasmine.any(Function));
expect(ctrl.results.length).toBe(1);
expect(ctrl.results[0]).toBe(modalResult);