【问题标题】:Why does test fails while browsers doesn't testing AngularJS apps?为什么在浏览器不测试 AngularJS 应用程序时测试会失败?
【发布时间】:2015-03-29 05:28:00
【问题描述】:

最近几天我一直在尝试测试 AngularJS 1.3.15 代码。今天它让我发疯了,给了我无法在普通 GUI 浏览器上重现的错误。

第一个问题是$routecurrent 属性。控制器如下:

...
.controller('HomeCtrl', ['$route', function($route) {
    var user = $route.current.locals.user;
...

上面会在测试时抛出错误,但它会在浏览器上显示任何错误。

测试输出

在 Chrome 中它失败了!

Chrome 41.0.2272 (Linux) Controller: HomeCtrl $controller.user should have an user FAILED
    TypeError: Cannot read property 'locals' of undefined
        at new <anonymous> (/home/lucio/chatbeats/app/app.js:26:28)

在 PhantomJS 中它失败了!

PhantomJS 1.9.8 (Linux) Controller: HomeCtrl $controller.user should have an user FAILED
    TypeError: Cannot read property 'locals' of undefined
        at new <anonymous> (/home/lucio/chatbeats/app/app.js:26:28)

浏览器输出

在 Chrome 中有效!

在 Firefox 中有效!

在 Chromium 中有效!

第二个问题是$scope。为了检查前面的问题不是由处理不当的异步调用引起的(如here 所述),我尝试使用$scope.$on 设置监听器:

...
.controller('HomeCtrl', ['$scope', '$route', function($scope, $route) {
    $scope.$on('$routeChangeError', function() {
      console.log($route.current);
    });
...

测试套件无法识别$scopeProvider,而浏览器会。

测试输出

在 Chrome 中它失败了!

Chrome 41.0.2272 (Linux) Controller: HomeCtrl $controller.user should not have the user signed in FAILED
    Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- HomeCtrl
    http://errors.angularjs.org/1.3.15/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20HomeCtrl

在 PhantomJS 中它失败了!

PhantomJS 1.9.8 (Linux) Controller: HomeCtrl should do something FAILED
    Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- HomeCtrl

浏览器输出

在 Chrome 中有效!

在 Firefox 中有效!

在 Chromium 中有效!

注意:我在同一个 grunt 任务下运行了两个应用程序,这意味着它们几乎同时运行。

使用的工具:

  • 茉莉花v2.2.0
  • 业力 v0.12.32
  • PhantomJS 1.9.8 (Linux)(用于 CLI 的单元测试)
  • Chrome 41.0.2272(用于 CLI 的单元测试)
  • Chrome 版本 42.0.2311.90(64 位)(用于从 GUI 手动测试)
  • Chromium 版本 41.0.2272.76 Ubuntu 14.10(64 位)(用于从 GUI 手动测试)
  • Firefox 版本 37.0.2(用于从 GUI 手动测试)

您可以通过here查看整个项目。

如果我在代码中遗漏了什么,请纠正我。

为什么会这样?有什么方法可以避免对 AngularJS 应用程序进行手动测试?

【问题讨论】:

    标签: javascript angularjs unit-testing google-chrome phantomjs


    【解决方案1】:

    $路线

    单元测试通常独立于路由,因此您看到的文档和大多数示例都没有在测试运行程序中包含 angular-route.js。这意味着在测试的应用程序中将不存在 $route 服务(因此未定义)。所以当你实例化一个以 $route 作为依赖的控制器时,你需要提供一个 mock 对象作为依赖,以模拟当前的路由状态。

    $controller('HomeCtrl', {
        $route: {
            current: {
                locals: {
                    user: { name: 'someUser' }
                }
            }
        }
    });
    

    $范围

    当 Angular 在浏览器中运行正常的应用程序期间为您实例化控制器时,控制器关联的范围会自动为您决定。在测试中,由于您是自己创建控制器,因此您还需要自己创建范围并将其分配给控制器。您可能在文档中遇到过以下内容。这只是创建一个新作用域作为 $rootScope 的子作用域,并将其作为控制器的依赖项传递。您使用新的范围而不是直接使用 $rootScope,这样您的测试就不会污染 $rootScope(也就是全局范围)。

    var scope = $rootScope.$new();
    
    $controller('HomeCtrl', {
        $scope: scope
    });
    

    两者结合:

    var scope = $rootScope.$new();
    
    $controller('HomeCtrl', {
        $scope: scope,
        $route: {
            current: {
                locals: {
                    user: { name: 'someUser' }
                }
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 2017-09-17
      • 2010-10-14
      相关资源
      最近更新 更多