如何在单元测试时将控制器注入指令中

Kla*_*urn 3 unit-testing dependency-injection controller directive angularjs

我想测试一个像这样声明的AngularJS指令

app.directive('myCustomer', function() {
    return {
      template: 'cust.html'
      controller: 'customerController'
    };
  });
Run Code Online (Sandbox Code Playgroud)

在测试中我想注入(或覆盖)控制器,这样我就可以只测试指令的其他部分(例如模板).该customerController过程可以被单独测试.这样我就可以清楚地分离测试.

  • 我试过通过在测试中设置controller属性来覆盖控制器.
  • 我试过注射customController使用$provide.
  • 我已经尝试设置ng-controller测试中使用的html指令声明.

我无法让任何人工作.问题似乎是我得到指令的引用,直到我得到$compile它.但是在编译之后,控制器已经设置好了.

 var element = $compile("<my-customer></my-customer>")($rootScope);
Run Code Online (Sandbox Code Playgroud)

gka*_*pak 10

一种方法是定义一个新模块(例如'specApp'),将你的app(例如'myApp')声明为依赖.然后使用'specApp'模块注册'customerController'控制器.这将有效地"隐藏"'myApp'的customerController,并在编译时将该模拟控制器提供给指令.
例如:

你的应用:

var app = angular.module('myApp', []);
...
app.controller('customerController', function ($scope,...) {
    $scope = {...};
    ...
});
app.directive('myCustomer', function () {
    return {
        template: 'cust.html',
        controller: 'customerController'
    };
});
Run Code Online (Sandbox Code Playgroud)

你的规格:

describe('"myCustomer" directive', function () {
    $compile;
    $newScope;

    angular.module('specApp', ['myApp'])
    /* Register a "new" customerController, which will "hide" that of 'myApp' */
    .controller('customerController', function ($scope,...) {
        $scope = {...};
        ...
    });

    beforeEach(module('specApp'));

    it('should do cool stuff', function () {
        var elem = angular.element('<div my-customer></div>');
        $compile(elem)($newScope);
        $newScope.$digest();
        expect(...
    });
});
Run Code Online (Sandbox Code Playgroud)

另请参阅此工作演示.


Tom*_*cer 6

我认为有一种比接受的答案更简单的方法,它不需要创建新模块.

你在尝试时很接近$provide,但是对于模拟控制器,你会使用不同的东西:$controllerProvider.使用register()规范中的方法模拟控制器.

beforeEach(module('myApp', function($controllerProvider) {
    $controllerProvider.register('customerContoller', function($scope) {
        // Controller Mock
    });
});
Run Code Online (Sandbox Code Playgroud)