使用父控制器方法调用测试Angular

时间:2015-02-25 13:10:48

标签: javascript angularjs unit-testing jasmine

我正在尝试首次为Angular应用程序编写单元测试。目前我在运行测试时遇到了一些问题。运行应用程序通常正常,它不会给出任何错误。但是,当使用Karma和Jasmine运行测试时,我收到以下错误:

TypeError: 'undefined' is not a function (evaluating '$scope.addActiveClassToMenuButton('menuButtonHome')')

我正在使用ui.router模块。不确定这是否重要。

父控制器

父控制器包含以下方法:

angular.module('testApp')
.controller('ParentCtrl', function ($scope, $resource) {

    $scope.addActiveClassToMenuButton = function(buttonId) {
        //Some code
    }

}

子控制器

子控制器调用parent方法,如下所示:

angular.module('testApp')
.controller('ChildCtrl', function ($scope, $resource) {

    $scope.addActiveClassToMenuButton('menuButtonHome');

}

子控制器测试文件

失败的测试文件:

describe('Child controller tests. ', function () {
    beforeEach(module('testApp'));

    var ChildCtrl, scope;

    beforeEach(inject(function ($controller, $rootScope) {
      scope = $rootScope.$new();
      ChildCtrl = $controller('ChildCtrl', {
        $scope: scope
      });
    }));

    it('simple false test', function () {
      expect(false).toBe(false);
    });
});

即使我还没有在测试中使用作用域,所有测试都会失败,因为代码找不到parent方法。

解决方案

将测试文件更改为此工作:

describe('Child controller tests. ', function () {
  beforeEach(module('testApp'));

  var controller, scope, parentScope, childScope;

  beforeEach(inject(function ($controller, $rootScope, $compile) {
    scope = $rootScope.$new();
    var el = angular.element('<div ng-controller="ParentCtrl"><div ng-controller="ChildCtrl"></div></div>');
    $compile(el)(scope);

    parentScope = el.scope();
    childScope = el.children().scope();
  }));

  it('simple false test', function () {
    expect(false).toBe(false);
  });

});

1 个答案:

答案 0 :(得分:4)

试试这个..

describe('Child controller tests. ', function () {
    beforeEach(module('testApp'));

    var ChildCtrl, scope;

    beforeEach(inject(function ($controller, $rootScope, $compile) {
      scope = $rootScope.$new();
      var el = angular.element('<div ng-controller="ParentCtrl"><div ng-controller="ChildCtrl"></div></div>');

      $compile(el)(scope);

      // to access parent controller.
      var parentScope = el.scope();
      var childScope = el.children().scope();

      // now you should be able to access from parent and child scopes.
    }));

    it('simple false test', function () {
      expect(false).toBe(false);
    });
});

这将首先实例化ParentCtrl,然后使用ChildCtrl的范围扩展它的范围。

在您给出的示例中,仅实例化了ChildCtrl,未实例化ParentCtrl。