嘲讽控制器实例化在角指令单元测试 [英] Mocking Controller Instantiation In Angular Directive Unit Test

查看:163
本文介绍了嘲讽控制器实例化在角指令单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是单元测试的角度指令,并想以某种方式在单元测试嘲笑或存根命名控制器的实例。

I am unit testing an Angular directive and would like to mock or stub in some way the instantiation of the named controller in the unit test.

所以,首先我想对一些code ...

So first I suppose on to some code...

'use strict';

angular.module('App.Directives.BreadCrumbs', [])

    .directive('kxBreadcrumbs', function () {
        return {
            restrict: 'E',
            controller: 'BreadCrumbsController',
            template:
                '<!-- Breadcrumbs Directive HTML -->' +

                '<ol class="breadcrumb">' +
                '    <li ng-repeat="crumb in crumbPath">' +
                '       <a ng-class="{true: \'disable\', false: \'\'}[crumb.last]" href="{{crumb.href}}" ng-click="updateCrumb(crumb.name)">{{crumb.name}}</a>' +
                '    </li>' +
                '</ol>' +

                '<!-- End of Breadcrumbs Driective HTML -->'
        };

    });

这是一个样的指令,我将单元测试,最重要的事情夺去这是命名控制器。

This is one sample directive that I would unit test, the important thing to take away from this is the named controller.

所以在我的单元测试

'use strict';

describe('Directives: Breadcrumbs', function () {

    var//iable declarations
        elm,
        scope,
        $rootScope
    ;

    beforeEach(function () {
        module('App.Directives.BreadCrumbs');
        module('App.Controllers.BreadCrumbs');
        module('App.Constants'); // <--- Comes from the controller dependancy
    });


    beforeEach(inject(function (_$rootScope_, $compile) {
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();

        elm = angular.element('<kx-breadcrumbs></kx-breadcrumbs>');
        $compile(elm)(scope);
        scope.$apply();
    }));

    it('Should create the breadcrumbs template', function () {
        scope.crumbPath = [{name: 'home', href: '/'},{name: 'coffee', href: '/coffee'},{name: 'milk', href: '/milk'}];
        scope.$apply();
        var listItem = $(elm).find('li');
        expect(listItem.length).toBe(3);
        expect($(listItem).text()).toContain('home');
        expect($(listItem).text()).toContain('coffee');
        expect($(listItem).text()).toContain('milk');

    });
});

可以看到3个模块列入 - 该指令时,控制器和第三个的常数。这是由控制器作为依赖关系所以为了拉进了单元测试,我需要在扶养或者更糟糕的情况下,从控制器的依赖关系拉this引用。但因为我不是在单位的指令单元测试测试控制器的功能,这似乎是多余的和腹胀code的通过包含模块。理想情况下,我想只包括我的单元测试的模块。

You can see the inclusion of the 3 modules - the directive, the controller and the third one the constants. This is referenced by the controller as a dependancy so in order to pull this into the unit test I need to pull in the dependancy or in much worse cases the dependancies from the controller. But as I am not unit testing the functionality of the controller in the directive unit test, this seem redundant and bloating of code through inclusion of modules. Ideally I would like to only include the module that I am unit testing.

  module('App.Directives.BreadCrumbs');

而不是(添加模块来举例说明我的观点更多)

and not (modules added to exemplify my point more)

  module('App.Directives.BreadCrumbs');
  module('App.Controllers.BreadCrumbs');
  module('App.Constants'); // <--- Comes from the controller dependancy
  module('App.Service.SomeService'); // <--- Comes from the controller dependancy
  module('App.Service.SomeOtherService'); // <--- Comes from the SomeService dependancy

当我们单元测试控制器,我们可以嘲笑那些传递服务完全或使用茉莉间谍。我们也能完成同样的事情八九不离十指令中的单元测试,所以我不必须遵循扶养线索?

When we unit test controllers we can mock services that are passed in either completely or by using jasmine spies. Can we accomplish the same sorta thing in unit test of directives so I don't have to follow the dependancy trail?

推荐答案

您可以通过创建模块配置块嘲笑 $ controllerProvider.register()的控制器, $ provide.provider() $ provide.factory() $ provide.service( ) $ provide.value()为供应商,工厂和服务:

You can create mocks in module configuration block by using $controllerProvider.register() for controllers, $provide.provider(), $provide.factory(), $provide.service() and $provide.value() for providers, factories and services:

的JavaScript

beforeEach(function () {
    module('App.Directives.BreadCrumbs', function($provide, $controllerProvider) {
        $controllerProvider.register('BreadCrumbsController', function($scope) {
            // Controller Mock
        });
        $provide.factory('someService', function() {
            // Service/Factory Mock
            return {
                doSomething: function() {}
            }
        });
    });
});

一旦你这样做,角将注入你的模拟 BreadCrumbsController 控制器进入 kxBreadcrumbs 指令。这样,您就不需要包括实时控制器和它的依赖到单元测试。

Once you do so, Angular will inject your mock BreadCrumbsController controller into kxBreadcrumbs directive. This way you don't need to include real controller and it's dependencies into unit test.

有关详细信息,请参阅角的官方文档:

For more information see Angular's official documentation on:

  • $provide
  • $controllerProvider

这篇关于嘲讽控制器实例化在角指令单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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