javascript - 为什么测试失败而浏览器不测试 AngularJS 应用程序?

标签 javascript angularjs unit-testing google-chrome phantomjs

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

第一个问题是 $routecurrent 属性。 Controller 如下:

...
.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 中它可以工作!

renders page correctly

在 Firefox 中它可以工作!

renders page correctly

在 Chromium 中它可以工作!

renders page correctly

第二个问题与$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 中它可以工作!

prints the object to console

在 Firefox 中它可以工作!

prints the object to console

在 Chromium 中它可以工作!

prints the object to console

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

使用的工具:

  • Jasmine v2.2.0
  • Karma 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 应用程序的手动测试吗?

最佳答案

$route

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

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

$范围

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

var scope = $rootScope.$new();

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

将两者结合起来:

var scope = $rootScope.$new();

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

关于javascript - 为什么测试失败而浏览器不测试 AngularJS 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29325942/

相关文章:

javascript - 只有一个段的 HighCharts 饼图不显示标签

javascript - Angularjs 服务方法未被调用,TypeError : Cannot read property '

ruby-on-rails - 在 Ruby on Rails 中,您测试 Controller 和 View 还是大多数模型?

android - 有没有办法在 AndroidTestCase 中打开和关闭连接?

javascript - 以编程方式使 div 元素在另一个 div 元素内垂直滚动

javascript - 向 NVD3 multiChart 添加额外的图表,缩短图表(由于图例)修复了什么?

javascript - AngularJS 路由和 anchor 哈希

javascript - 如何在 mongodb 的 angularjs 中使用变量模式

javascript - 单元测试中的变量范围问题

javascript - Backbone.js View 是否需要 jQuery 或 Zepto? (或 : why am I getting “Uncaught TypeError: undefined is not a function” ? )