unit-testing - Angularjs:angular-phonecat 教程应用程序第一次单元测试失败

标签 unit-testing angularjs jasmine

刚开始学习 Angularjs 和 jasmine 单元测试...

跟随教程 http://docs.angularjs.org/tutorial/step_02发现第一个单元测试(应该通过,因为 scope.phones.length 是 3)失败。

INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 30.0.1599 (Mac OS X 10.8.5)]: Connected on socket BdjA1lVT9OOo8kgQKLYs
Chrome 30.0.1599 (Mac OS X 10.8.5) PhoneCat controllers PhoneListCtrl should create "phones" model with 3 phones FAILED
    ReferenceError: PhoneListCtrl is not defined
        at null.<anonymous> (/Applications/MAMP/htdocs/angular-phonecat/test/unit/controllersSpec.js:12:22)
Chrome 30.0.1599 (Mac OS X 10.8.5): Executed 2 of 2 (1 FAILED) (0.37 secs / 0.033 secs)

所以基本上,它说明 PhoneListCtrl 没有定义。但是该应用程序运行良好,考虑到我在教程的开头,我真的不知道从哪里开始!

这是我的单元测试,这是教程中的默认设置。

测试/单元/controllerSpec.js
'use strict';

/* jasmine specs for controllers go here */
describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){

    beforeEach(module('phonecatApp'));

    it('should create "phones" model with 3 phones', function() {
      var scope = {},
          ctrl = new PhoneListCtrl(scope);

      expect(scope.phones.length).toBe(3);
    });

    it('should create "phones" model with 3 phones', inject(function($controller) {
      var scope = {},
          ctrl = $controller('PhoneListCtrl', {$scope:scope});

      expect(scope.phones.length).toBe(3);
    }));

  });
});

应用程序/js/controller.js
'use strict';

/* Controllers */

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function PhoneListCtrl($scope) {
  $scope.phones = [
    {'name': 'Nexus S',
     'snippet': 'Fast just got faster with Nexus S.'},
    {'name': 'Motorola XOOM™ with Wi-Fi',
     'snippet': 'The Next, Next Generation tablet.'},
    {'name': 'MOTOROLA XOOM™',
     'snippet': 'The Next, Next Generation tablet.'}
  ];
  $scope.hello = "Hello World";
});

配置/karma.conf.js http://pastebin.com/PPWjSmyJ

最佳答案

示例中有 2 个单元测试(2 个 it block )。他们看起来应该做同样的事情,但只有第二个实际创建了您的 Controller 。

当您以 Angular 定义 Controller 时,它不是一个全局可用的对象,您可以使用 new Controller(...) 进行初始化.您必须从 Angular 请求它。

您的第二个测试(似乎通过了)通过注入(inject) $controller 来做到这一点。服务将执行设置和请求 Controller 所需的任何操作。

inject(function($controller) { ... });

然后它像这样使用这个服务创建 Controller
var scope = {},
    ctrl = $controller('PhoneListCtrl', {$scope:scope});

在您的第一个测试中,您尝试只使用 PhoneListCtrl直接变量。正如错误所说,除非您在函数中定义具有该名称的变量,否则这不存在。

我刚刚注意到教程中的测试失败。如果您在全局命名空间上定义了一个 Controller ,这是专门针对的。例如
function PhoneListCtrl($scope) {
  $scope.phones = [
    {'name': 'Nexus S',
     'snippet': 'Fast just got faster with Nexus S.'},
    {'name': 'Motorola XOOM™ with Wi-Fi',
     'snippet': 'The Next, Next Generation tablet.'},
    {'name': 'MOTOROLA XOOM™',
     'snippet': 'The Next, Next Generation tablet.'}
  ];
  $scope.hello = "Hello World";
};
phonecatApp.controller('PhoneListCtrl', PhoneListCtrl);

然后测试将起作用,因为您已在全局范围内定义了用作 Controller 的函数,因此您可以在不注意它是 Controller 的情况下对其进行测试。这意味着如果您尝试使用其他服务,您将不得不自己注入(inject)它们并执行$controller 的任何操作。会为你做的。

关于unit-testing - Angularjs:angular-phonecat 教程应用程序第一次单元测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19403472/

相关文章:

ruby-on-rails - 如何在不删除数据库内容的情况下运行 Rails 集成测试?

javascript - 在 Angular.js 中扩展 $scope

javascript - 如何从渲染的 html 将初始数据添加到 angularjs 应用程序

visual-studio - 代码覆盖率结果定期给出: Empty results generated

c# - 使用 Rhino Mocks 模拟阻塞调用

Angular 5 : Unit testing getters and setters

javascript - 单元测试 Angular 指令点击处理程序

mysql - PHP MySQL 数据到 AngularJS

requirejs - Karma/Jasmine 测试失败,错误为 : 'Uncaught Error: Module name "simple_test. js“尚未加载上下文 : _. 使用 require([])”

javascript - Angular 2 的 Jasmine 测试用例 - 导航到其他页面