使用自己的控制器测试Angular Directive

时间:2013-06-26 18:36:04

标签: angularjs angularjs-directive

我正在尝试为AngularJS指令编写单元测试,该指令使用与页面上的控制器不同的单独控制器。但是,我无法找到从我的测试中访问该控制器的任何方法。

这是我的指示:

'use strict';
angular.module('myapp.directives')
  .directive('searchButton', function () {
    function SearchButtonCtrl ($scope, $location) {
      $scope.search = function () {
        $location.path('/search');
        $location.search(q, $scope.query.w);
      };
    }
    return {
      template: '<input type="text" ng-model="query.q">',
      controller: SearchButtonCtrl,
      restrict: 'E'
    };
  });

是否可以访问SearchButtonCtrl?或者是否有更好的方法来构建我的代码以便可以访问它?

1 个答案:

答案 0 :(得分:2)

在这种情况下,您最终访问控制器的方法是使用控制器放置在其范围内的功能,该功能将构成测试输入的HTML片段。

注意:使用jasmine间谍在这里可能有点过头了,我没有花时间查找正确的方法来匹配$ location.path()和/或$ location.search()的参数,但这应该足以帮助你找到你正在寻找的观察地点。

'use strict';

describe('Directive: Search', function() {

    var element, $location;

    // Load your directive module with $location replaced by a test mock.
    beforeEach( function() {
        module('myapp.directives'), function() {
            $provide.decorator('$location', function($delegate) {
                $delegate.path = jasmine.createSpy();
                $delegate.search = jasmine.createSpy();

                return $delegate;
            });
        });

        inject(function(_$location_) {
            $location = _$location_;
        });
    });

    it('changes the path', function() {
        // Arrange to trigger your directive code
        element = $element.html('<span ng-init="query.q = 'xyz'"><search><span ng-init="search()"></span></search></span>' );

        // Express your directive's intended behavior
        expect($location.path).toHaveBeenCalled();
    });

    it('changes a search param', function() {
        // Arrange to trigger your directive code
        element = $element.html('<span ng-init="query.q = 'xyz'"><search><span ng-init="search()"></span></search></span>' );

        // Express your directive's intended behavior
        expect($location.search).toHaveBeenCalled();
    });
});