繁体   English   中英

单元测试angular-bootstrap $ modal

[英]Unit testing angular-bootstrap $modal

我在尝试为Angular-Bootstrap $modal编写茉莉花单元测试时遇到问题。 确切的错误是Expected spy open to have been called with [ { templateUrl : '/n/views/consent.html', controller : 'W2ConsentModal as w2modal', resolve : { employee : Function }, size : 'lg' } ] but actual calls were [ { 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('Should correctly show the W2 consent modal', function () {
            var employee = terminatedaccessMocks.getCurrentUserInfo();

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



    });

尝试这个:

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: jasmine.any(Function)
            },
            size: 'lg'
        };

        var actualOptions;

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

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

                spyOn(modal, 'open').and.callFake(function(options){
                    actualOptions = options;

                    return fakeModal;
                });

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

            });

        });

        it('Should correctly show the W2 consent modal', function () {
            var employee = { name : "test"};

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

普拉克

说明

我们不应期望实际的resolve.employee与假的resolve.employee相同,因为resolve.employee是一个返回员工的函数(在这种情况下,员工在关闭中被捕获)。 该函数可以是相同的,但在运行时返回的对象可能不同。

您的测试失败的原因是javascript比较函数的方式。 看看这个小提琴 无论如何,我不关心这个,因为我们不应该期待功能实现 在这种情况下我们关心的是resolve.employee返回我们传入的同一个对象:

expect(actualOptions.resolve.employee()).toEqual(employee);

所以这里的解决方案是:我们期望除resolve.employee之外的所有内容:

var modalOptions = {
                templateUrl: '/n/views/consent.html',
                controller: 'W2ConsentModal as w2modal',
                resolve: {
                    employee: jasmine.any(Function) //don't care about the function as we check it separately.
                },
                size: 'lg'
            };

   expect(modal.open).toHaveBeenCalledWith(modalOptions);

首先通过捕获它来单独检查resolve.employee

var actualOptions;

 spyOn(modal, 'open').and.callFake(function(options){
      actualOptions = options; //capture the actual options               
      return fakeModal;
 });

expect(actualOptions.resolve.employee()).toEqual(employee); //Check the returned employee is actually the one we pass in.

这是一个通过引用传递vs传递值的问题。 resolve.employee中使用匿名函数$modal.open

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)
}

如果必须测试resolve函数,则应将其暴露在可以在测试中获得对同一函数的引用的位置。

我不确定这对你现在是否会有所帮助,但是当你监视某些东西时你可以获得传递给$ uibModal.open间谍的参数,然后你可以调用该函数来测试它是否返回了resolve方法中的内容。

it('expect resolve to be have metadataid that will return 9999', () => {
            spyOn($uibModal, 'open');
            //add test code here that will call the $uibModal.open
            var spy = <jasmine.Spy>$uibModal.open;
            var args = spy.calls.argsFor(0);
            expect(args[0].resolve.metadataId()).toEqual(9999);
});

*****我的代码使用的是打字稿,但这对我有用。**

我遇到过同样的情况。 我已经遇到了下面给出的解决方案的问题

//Function to open export modal
scope.openExportModal();
expect( uibModal.open ).toHaveBeenCalledWith(options);
expect( uibModal.open.calls.mostRecent().args[0].resolve.modalData() ).toEqual(modalData);

希望如果您想要快速修复,这可能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM