1

我正在尝试为 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?或者有没有更好的方法来构造我的代码以便可以访问它?

4

1 回答 1

2

在这种情况下,您最终访问控制器的方式是使用控制器从 HTML 片段中放置在其范围内的函数,该 HTML 片段将形成您的测试输入。

注意:这里使用 jasmine spy 可能有点矫枉过正,我没有花时间查找正确的方法来匹配 $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();
    });
});
于 2013-06-27T03:33:47.060 回答