角度单元测试:调用另一个控制器中定义的方法抛出'undefined'不是错误

 苏格兰的秋天 发布于 2023-02-07 07:01

我正在尝试测试AngularJS文件,但它无法调用另一个Controller中定义的方法.

在MyPage文件中:

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

pageChecker()方法在MyApplication控制器的App.js中定义,并返回true或false.

为了完整起见:

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

茉莉花文件是:

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();
  });
});

我得到"TypeError:'undefined'不是一个函数(评估'$ scope.pageChecker()')

我想覆盖pageChecker方法以始终返回true.我该怎么做呢?

编辑:感谢Dskh,我有我的答案,还有我的另一个调整:

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();
  });
});

Dan.. 7

当你执行$ rootScope.$ new()时,你自己创建$ scope,然后将它注入你使用$ controller()方法时创建的控制器中.

因此,如果您希望该方法始终返回true,则只需自己创建该方法:

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

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

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

更多解释:当您的应用程序正在运行时,$ scope会通过angular自动注入您的控制器.在您的测试中,您只是单独测试控制器,因此您需要自己创建范围对象并伪造您想要的任何行为.使用$ rootScope().$ new()将为您提供$ watch或$ on等角度方法,但您需要自己重新创建自己的方法.

1 个回答
  • 当你执行$ rootScope.$ new()时,你自己创建$ scope,然后将它注入你使用$ controller()方法时创建的控制器中.

    因此,如果您希望该方法始终返回true,则只需自己创建该方法:

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

    更多解释:当您的应用程序正在运行时,$ scope会通过angular自动注入您的控制器.在您的测试中,您只是单独测试控制器,因此您需要自己创建范围对象并伪造您想要的任何行为.使用$ rootScope().$ new()将为您提供$ watch或$ on等角度方法,但您需要自己重新创建自己的方法.

    2023-02-07 07:26 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有