javascript - Angular unit testing: Calling a method defined in another controller is throwing 'undefined' is not

I am trying to test an AngularJS file, but it can't call a method defined in another Controller.In

I am trying to test an AngularJS file, but it can't call a method defined in another Controller.

In the MyPage file:

angular.module('MyApplication').controller('MyPageCtrl', function ($scope, $rootScope) {
  if($scope.pageChecker) {
    $scope.doSomething();
  }
}

The pageChecker() method is defined in App.js, in the MyApplication controller, and returns true or false.

For the sake of pleteness:

$scope.pageChecker = function() {
  if(cookieCheck) {
    return true;
  }
  else {
    return false;
  }
};

The jasmine file is:

describe("Page check", function(){
  beforeEach(angular.mock.module('MyApplication'));

  beforeEach(angular.mock.inject(function ($rootScope, $controller) {
    var $scope = $rootScope.$new();
    $controller('MyPageCtrl', { $scope: $scope});
  }));

  it("should call $scope.doSomething", function(){
    spyOn($scope, "doSomething");
    $scope.doSomething();
    expect($scope.doSomething).toHaveBeenCalled();
  });
});

I get "TypeError: 'undefined' is not a function (evaluating '$scope.pageChecker()')

I want to override the pageChecker method to always return true. How do I do this?

EDIT: Thanks to Dskh, I have my answer, with another tweak from me:

describe("Page check", function(){

  var $scope; //declare here, else it is a local variable inside the beforeEach

  beforeEach(angular.mock.module('MyApplication'));

  beforeEach(angular.mock.inject(function ($rootScope, $controller) {
    $scope = $rootScope.$new();
    // define the overriding methods here
    $scope.pageChecker = function(){
      return true;
    };
    // end overriding methods here
    $controller('MyPageCtrl', { $scope: $scope});
  }));

  it("should call $scope.doSomething", function(){
    spyOn($scope, "doSomething");
    $scope.doSomething();
    expect($scope.doSomething).toHaveBeenCalled();
  });
});

I am trying to test an AngularJS file, but it can't call a method defined in another Controller.

In the MyPage file:

angular.module('MyApplication').controller('MyPageCtrl', function ($scope, $rootScope) {
  if($scope.pageChecker) {
    $scope.doSomething();
  }
}

The pageChecker() method is defined in App.js, in the MyApplication controller, and returns true or false.

For the sake of pleteness:

$scope.pageChecker = function() {
  if(cookieCheck) {
    return true;
  }
  else {
    return false;
  }
};

The jasmine file is:

describe("Page check", function(){
  beforeEach(angular.mock.module('MyApplication'));

  beforeEach(angular.mock.inject(function ($rootScope, $controller) {
    var $scope = $rootScope.$new();
    $controller('MyPageCtrl', { $scope: $scope});
  }));

  it("should call $scope.doSomething", function(){
    spyOn($scope, "doSomething");
    $scope.doSomething();
    expect($scope.doSomething).toHaveBeenCalled();
  });
});

I get "TypeError: 'undefined' is not a function (evaluating '$scope.pageChecker()')

I want to override the pageChecker method to always return true. How do I do this?

EDIT: Thanks to Dskh, I have my answer, with another tweak from me:

describe("Page check", function(){

  var $scope; //declare here, else it is a local variable inside the beforeEach

  beforeEach(angular.mock.module('MyApplication'));

  beforeEach(angular.mock.inject(function ($rootScope, $controller) {
    $scope = $rootScope.$new();
    // define the overriding methods here
    $scope.pageChecker = function(){
      return true;
    };
    // end overriding methods here
    $controller('MyPageCtrl', { $scope: $scope});
  }));

  it("should call $scope.doSomething", function(){
    spyOn($scope, "doSomething");
    $scope.doSomething();
    expect($scope.doSomething).toHaveBeenCalled();
  });
});
Share Improve this question edited Jan 2, 2014 at 16:48 Jezcentral asked Jan 2, 2014 at 15:20 JezcentralJezcentral 4224 silver badges18 bronze badges 2
  • 1 I think there's a typo in the question, I don't see any call to $scope.pageChecker() as a function call. It looks like your controller calls the $scope.pageChecker method as part of the controller instantiation, and when you're providing the scope object in controller creation in the test it indeed doesn't have a pageChecker method – Eitan Peer Commented Jan 2, 2014 at 15:34
  • Good catch, Eitan, but not the cause of the problem. This was a names-have-been-changed-to-protect-the-innocent version of my code, as my employer would not like me posting actual code. :) – Jezcentral Commented Jan 2, 2014 at 16:00
Add a ment  | 

1 Answer 1

Reset to default 7

You create the $scope yourself when you do $rootScope.$new(), and then you inject it into the controller you create when you use the $controller() method.

Therefore, if you want that method to always return true, you just need to create the method yourself:

beforeEach(angular.mock.inject(function ($rootScope, $controller) {
    var $scope = $rootScope.$new();

    $scope.doSomething = function(){
        return true;
    };

    $controller('MyPageCtrl', { $scope: $scope});
  }));

Some more explanation: When your app is running for real, $scope is injected automatically into your controller by angular. In your test you are just testing your controller in isolation, so you need to create the scope object yourself and fake any behaviour you want from it. Using $rootScope().$new() will give you the angular methods like $watch or $on, but you need to recreate your own methods yourself.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744310772a4567935.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信