单元测试angular-bootstrap $modal

IT小君   2023-05-12T01:30:25

我试图为一个Angular-Bootstrap $modal编写Jasmine单元测试,但是遇到了问题。精确的错误是预期调用spy open,使用 [ { templateUrl : '/n/views/consent.html', controller : 'W2ConsentModal as w2modal', resolve : { employee : Function }, size : 'lg' } ] ,但实际调用是 [ { templateUrl : '/n/views/consent.html', controller : 'W2ConsentModal as w2modal', resolve : { employee : Function }, size : 'lg' } ]

预期和实际的模态框选项对象是相同的。发生了什么?

控制器

(function () {
    'use strict';

    angular
        .module('app')
        .controller('W2History', W2History);

    W2History.$inject = ['$scope', '$modal', 'w2Service'];

    function W2History($scope, $modal, w2Service) {
        /* jshint validthis:true */
        var vm = this;
        vm.showModal = showModal;

        function showModal(employee) {
            var modalInstance = $modal.open({
                templateUrl: '/n/views/consent.html',
                controller: 'W2ConsentModal as w2modal',
                resolve: {
                    employee: function () {
                        return employee;
                    }
                },
                size: 'lg'
            });

            modalInstance.result.then(function (didConsent) {
                // code omitted
            });
        }


    }
})();

测试

 describe('W2History controller', function () {
        var controller, scope, modal;

        var fakeModal = {
            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 modalOptions = {
            templateUrl: '/n/views/consent.html',
            controller: 'W2ConsentModal as w2modal',
            resolve: {
                employee: function () {
                    return employee;
                }
            },
            size: 'lg'
        };

        beforeEach(function () {
            module('app');

            inject(function (_$controller_, _$rootScope_, _$modal_) {
                scope = _$rootScope_.$new();                         
                modal = _$modal_;

                spyOn(modal, 'open').and.returnValue(fakeModal);

                controller = _$controller_('W2History', {
                    $scope: scope,
                    $modal: modal,
                    w2Service: w2Srvc
                });

            });

        });

        it('应该正确显示W2同意模态框', function () {
            var employee = terminatedaccessMocks.getCurrentUserInfo();

            controller.showModal(employee);
            expect(modal.open).toHaveBeenCalledWith(modalOptions);
        });



    });
评论(4)
IT小君

这是一个关于按引用传递和按值传递的问题。在$modal.open中使用的resolve.employee匿名函数:

var modalInstance = $modal.open({
    templateUrl: '/n/views/consent.html',
    controller: 'W2ConsentModal as w2modal',
    resolve: {
        employee: function () {
            return employee;
        }
    },
    size: 'lg'
});

与你的测试中的resolve.employee匿名函数不同(按引用):

var modalOptions = {
    templateUrl: '/n/views/consent.html',
    controller: 'W2ConsentModal as w2modal',
    resolve: {
        employee: function () {
            return employee;
        }
    },
    size: 'lg'
};

你的测试应该是:

resolve: {
    employee: jasmine.any(Function)
}

如果解析函数的测试至关重要,你应该将其公开到测试中可以引用的地方。

2023-05-12T01:31:48   回复
IT小君

我不确定这能否帮到你,但当你对某个东西进行监视时,可以获取传递给 $uibModal.open 间谍的参数,然后调用该函数以测试它返回 resolve 方法中的内容。

it('期望 resolve 具有将返回 9999 的 metadataid', () => {
            spyOn($uibModal, 'open');
            //在这里添加测试代码,将调用 $uibModal.open
            var spy = <jasmine.Spy>$uibModal.open;
            var args = spy.calls.argsFor(0);
            expect(args[0].resolve.metadataId()).toEqual(9999);
});

*****我的代码使用 TypeScript,但对我而言这很有效。

2023-05-12T01:32:08   回复