【问题标题】:$scope.alerts undefined when doing unit testing client side with angularjs and jasmine使用 angularjs 和 jasmine 对客户端进行单元测试时,$scope.alerts 未定义
【发布时间】:2015-05-06 17:46:41
【问题描述】:

我正在为我的控制器编写单元测试。我正在用 jasmine 测试 userSave() 函数,并想检查作为数组的 $scope.alerts 变量的内容。但是$scope.alerts 在退出userSave() 函数时是空的,所以我无法检查它的内容。我不知道为什么它是空的,因为$scope.alerts 是全球性的。下面是我的控制器和测试用例的代码。

控制器

'use strict';

angular.module('myApp')
  .controller('RegisterCtrl', function ($scope, $http, $location) {
$scope.message = 'Register Route';

$scope.init = function () {
  $scope.inviteCode = $location.hash();
};
$scope.init();
$scope.master = {};

// Array to hold alert messages
$scope.alerts = [];

$scope.closeAlert = function (index) {
  $scope.alerts.splice(index, 1);
};

$scope.userSave = function (user) {
  /*jshint unused: false */
  $http.post('api/users/v1/', {
    'invite_code': $scope.inviteCode,
    'password': user.password,
    'last_name': user.lastName,
    'first_name': user.firstName
  }).success(function (data, status, headers, config) {
    $location.url($location.path());
    $location.path('/');
  }).error(function (data, status, headers, config) {
    if (status === 404) {
      $scope.alerts.push({
        type: 'danger',
        msg: 'Your invitation code has expired or is invalid, your registration will require a new one to be completed'
      });
    } else if (status === 204) {
      $scope.alerts.push({
        type: 'danger',
        msg: 'This email already exists, please click login and forgot your password to recover your password'
      });
    } else {
      $scope.alerts.push({
        type: 'danger',
        msg: 'There was an error registering'
      });
    }
  });
};
});

测试用例

   'use strict';

describe('Controller: RegisterCtrl', function () {

  // load the controller's module
  beforeEach(module('myApp'));

  var RegisterCtrl, scope, httpBackend,http;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, $httpBackend,$http) {
    scope = $rootScope.$new();
    httpBackend = $httpBackend;
    http = $http;
    RegisterCtrl = $controller('RegisterCtrl', {
      $scope: scope
    });
  }));
  afterEach(function() {
    httpBackend.verifyNoOutstandingExpectation();
    httpBackend.verifyNoOutstandingRequest();
  });

it('should return a 404 for expired inviteCode', function () {
    var userClientPayload = {
      lastName: 'pav',
      firstName: 'nga',
      password: 'test'
    };
    var userServerPayload = {
      invite_code: 'expiredCode',
      last_name: 'pav',
      first_name: 'nga',
      password: 'test'
    };
    httpBackend.whenPOST('api/users/v1/',userServerPayload).respond(404);
    scope.inviteCode = 'expiredCode';
    scope.userSave(userClientPayload);
    //httpBackend.expectPOST('api/users/v1/',userServerPayload).respond(404);
    console.log(scope.alerts);
    expect(scope.alerts.type).toBe('danger');
    expect(scope.alerts.msg).toBe('Your invitation code has expired or is invalid, your registration will require a new one to be completed');
    httpBackend.flush();
  });
});

错误

Controller: RegisterCtrl should return a 404 for expired inviteCode FAILED
    Expected undefined to be 'danger'.
        at /Users/z001hm0/Documents/api_portal/developer-portal/client/test/unit/controllers/register.controller.spec.js:59
    Expected undefined to be 'Your invitation code has expired or is invalid, your registration will require a new one to be completed'.
        at /Users/z001hm0/Documents/api_portal/developer-portal/client/test/unit/controllers/register.controller.spec.js:60

【问题讨论】:

    标签: angularjs unit-testing angularjs-scope jasmine karma-jasmine


    【解决方案1】:

    $scope.alerts 是一个数组,所以这一行失败 b/c 一个数组没有 type 属性:

    expect(scope.alerts.type).toBe('danger');
    

    将上面的行替换为如下内容:

    expect(scope.alerts.length).toBe(1);
    expect(scope.alerts[0].type).toBe('danger');
    

    编辑

    下一个问题是您在调用httpBackend.flush() 之前调用了expect()。对flush() 的调用是在您的测试中发生模拟服务器响应的原因,这将触发填充$scope.alerts 的代码。

    因此,如果我们翻转这些代码行,它会如下所示:

    httpBackend.flush();
    expect(scope.alerts.length).toBe(1);
    expect(scope.alerts[0].type).toBe('danger');
    

    【讨论】:

    • 谢谢,但它说 scope.alerts.length 是 0
    • @user3137376 好的,这样就解决了第一个问题(尝试访问数组上不存在的名为“type”的属性)。我将编辑我的答案以解决下一个问题...
    • D,非常感谢,它有效,我不知道。非常感谢。
    猜你喜欢
    • 2013-06-29
    • 1970-01-01
    • 2015-10-12
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多