单元测试角引导模式$ [英] Unit testing angular-bootstrap $modal

查看:135
本文介绍了单元测试角引导模式$的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试写一个角度,引导 $模式茉莉花单元测试的问题。确切的错误是
预计间谍开放已调用[{templateUrl:/n/views/consent.html',控制器:'W2ConsentModal为w2modal,解决:{员工:功能},尺寸:'LG' }],但实际通话效果[{templateUrl:/n/views/consent.html',控制器:'W2ConsentModal为w2modal,决心:{员工:功能},尺寸:'LG'}]

预期与实际模态选项对象是相同的。这是怎么回事?

控制器

 (函数(){
    使用严格的;    角
        .module(应用)
        .controller('W2History',W2History);    。W2History $注射='$范围,$模式','w2Service'];    功能W2History($范围,$莫代尔,w2Service){
        / * jshint validthis:真* /
        VAR VM =这一点;
        vm.showModal =的ShowModal;        功能的ShowModal(员工){
            VAR modalInstance = $ modal.open({
                templateUrl:/n/views/consent.html',
                控制器:'W2ConsentModal为w2modal,
                解析:{
                    员工:功能(){
                        返回雇员;
                    }
                },
                大小:LG
            });            modalInstance.result.then(功能(didConsent){
                // code省略
            });
        }
    }
})();

测试

 描述('W2History控制器',函数(){
        VAR控制器,适用范围,模态;        VAR fakeModal = {
            结果:{
                那么:功能(confirmCallback,cancelCallback){
                    //存储供以后的回调时,在对话框的确定​​或取消按钮,用户点击
                    this.confirmCallBack = confirmCallback;
                    this.cancelCallback = cancelCallback;
                }
            },
            关闭:函数(项目){
                //用户点击了模态对话框OK,调用与所选项目的存储确认回调
                this.result.confirmCallBack(项目);
            },
            解雇:函数(类型){
                //用户点击模态对话框取消,调用存储取消回调
                this.result.cancelCallback(类型);
            }
        };        VAR modalOptions = {
            templateUrl:/n/views/consent.html',
            控制器:'W2ConsentModal为w2modal,
            解析:{
                员工:功能(){
                    返回雇员;
                }
            },
            大小:LG
        };        beforeEach(函数(){
            模块(应用);            注(功能(_ $ controller_,_ $ rootScope_,_ $ modal_){
                范围= _ $ rootScope _ $新的()。
                模式= _ $ modal_;                spyOn(模态,开放)and.returnValue(fakeModal)。                控制器= _ $ _控制器('W2History',{
                    $适用范围:适用范围,
                    $模式:模式,
                    w2Service:w2Srvc
                });            });        });        它('应正确显示W2同意模式',函数(){
            变种雇员= terminatedaccessMocks.getCurrentUserInfo();            controller.showModal(员工);
            期待(modal.open).toHaveBeenCalledWith(modalOptions);
        });    });


解决方案

试试这个:

 描述('W2History控制器',函数(){
        VAR控制器,适用范围,模态;        VAR fakeModal = {
            结果:{
                那么:功能(confirmCallback,cancelCallback){
                    //存储供以后的回调时,在对话框的确定​​或取消按钮,用户点击
                    this.confirmCallBack = confirmCallback;
                    this.cancelCallback = cancelCallback;
                }
            },
            关闭:函数(项目){
                //用户点击了模态对话框OK,调用与所选项目的存储确认回调
                this.result.confirmCallBack(项目);
            },
            解雇:函数(类型){
                //用户点击模态对话框取消,调用存储取消回调
                this.result.cancelCallback(类型);
            }
        };        VAR modalOptions = {
            templateUrl:/n/views/consent.html',
            控制器:'W2ConsentModal为w2modal,
            解析:{
                员工:jasmine.any(功能)
            },
            大小:LG
        };        VAR actualOptions;        beforeEach(函数(){
            模块('plunker');            注(功能(_ $ controller_,_ $ rootScope_,_ $ modal_){
                范围= _ $ rootScope _ $新的()。
                模式= _ $ modal_;                spyOn(模态,开放)。and.callFak​​e(功能(选件){
                    actualOptions =选择;                    返回fakeModal;
                });                控制器= _ $ _控制器('W2History',{
                    $适用范围:适用范围,
                    $模式:模式
                });            });        });        它('应正确显示W2同意模式',函数(){
            VAR员工= {名称:测试};            controller.showModal(员工);
            期待(modal.open).toHaveBeenCalledWith(modalOptions);
            期待(actualOptions.resolve.employee())toEqual(员工)。
        });
    });

普拉克

说明

我们不应该指望实际 resolve.employee 来与假冒相同 resolve.employee ,因为 resolve.employee 是返回雇员(在这种情况下,员工在结束捕获)的功能。该功能可以是相同的,但是在运行时返回的对象可以是不同的。

您的测试失败的原因是JavaScript的功能进行比较的方式。看看这个小提琴。反正我不关心这个,因为我们不应该期望的函数实现。我们在这种情况下在意什么是 resolve.employee 因为我们传递返回相同的对象:

 预期(actualOptions.resolve.employee())toEqual(员工)。

因此​​,这里的解决方案是:
我们期望的一切除了 resolve.employee

  VAR modalOptions = {
                templateUrl:/n/views/consent.html',
                控制器:'W2ConsentModal为w2modal,
                解析:{
                    员工:jasmine.any(功能)//不关心的功能,因为我们分开检查。
                },
                大小:LG
            };   期待(modal.open).toHaveBeenCalledWith(modalOptions);

检查 resolve.employee 分别由第一捕获它:

  VAR actualOptions; spyOn(模态,开放)。and.callFak​​e(功能(选件){
      actualOptions =选择; //获得实际的选择
      返回fakeModal;
 });期待(actualOptions.resolve.employee())toEqual(员工)。 //检查返回的员工其实是我们传递之一。

I'm having problems trying to write a jasmine unit test for an Angular-Bootstrap $modal. The exact error is 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' } ]

The expected and actual modal options object are the same. What is going on?

Controller

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


    }
})();

Test

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



    });

解决方案

Try this:

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

PLUNK

Explanation:

We should not expect the actual resolve.employee to be the same with the fake resolve.employee because resolve.employee is a function which returns an employee (in this case the employee is captured in closure). The function could be the same but at runtime the returned objects could be different.

The reason your test is failing is the way javascript compares functions. Take a look at this fiddle. Anyway, I don't care about this because we should not expect function implementations. What we do care about in this case is the resolve.employee returns the same object as we pass in:

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

So the solution here is: We expect everything except for the 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);

Check the resolve.employee separately by capturing it first:

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.

这篇关于单元测试角引导模式$的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆