【问题标题】:How to unit test promise/callback chains in AngularJS?如何在 AngularJS 中对承诺/回调链进行单元测试?
【发布时间】:2015-10-21 18:40:59
【问题描述】:

我正在为我的模型的 CRUD 操作使用生成的库(LoopBack 的 Angular SDK),并且发现很难对使用它们的控制器和服务进行单元测试。

这是一个我正在创建组织的示例,在完成该请求后,我为该组织创建了一个管理员(需要该组织的 ID,这就是我等待创建管理员的原因)。

$scope.createOrganization = function () {
  var newOrg = {
    name: $scope.organization.name,
    description: $scope.organization.description,
    location: $scope.organization.location
  };

  Organization.create(newOrg, createAdmin);
};

var createAdmin = function (organization) {
  var newAdmin = {
    name: $scope.organization.admin.name,
    email: $scope.organization.admin.email,
    password: $scope.organization.admin.password,
    organizationId: organization.id
  };

  Admin.create(newAdmin, function () {
    AuthService.login({ email: newAdmin.email, password: newAdmin.password }).then(function () {
      $state.go('admin.dashboard');
    });
  });
};

Organization.createAdmin.create 是 LoopBack SDK 中的方法,我不想碰它们。它们不使用典型的 Angular 承诺语法 (Service.method().then()),而是将回调函数作为参数(或者,您可以选择使用 Organization.create(newOrg).$promise.then(createAdmin)

我对此的测试看起来像:

it('should create an organization and admin when submitted', inject(function (Organization, Admin) {
  scope.organization = mockOrg; // object with all fields filled in
  spyOn(Organization, 'create');
  spyOn(Admin, 'create');
  scope.createOrganization();
  expect(Organization.create).toHaveBeenCalledWith({
    name: mockOrg.name,
    description: mockOrg.description,
    location: mockOrg.location
  }, Function);
}));

最后我不知所措。不知道如何编写一个测试来测试是否使用正确的信息调用了两个创建函数(最重要的是,我需要测试在组织创建之后 调用了 Admin,并且它传递了一个organization.id 变量)。

【问题讨论】:

  • 如果你想使用承诺,你应该承诺你的回调函数,而不是通过.then将承诺代码放在那些回调链中。您的主要问题是 createOrganisationcreateAdmin 既不接受回调也不返回承诺,这使得它们确实无法使用(不仅无法测试)。

标签: javascript angularjs unit-testing jasmine loopbackjs


【解决方案1】:

Organization.create 和 Admin.create 是 LoopBack SDK 中的方法,我不想接触它们。它们不使用典型的 Angular 承诺语法(Service.method().then()),而是将回调函数作为参数(或者,您可以选择使用 Organization.create(newOrg).$promise.then (createAdmin)。

LoopBack SDK for AngularJS 在底层使用ngResource,API 遵循 ngResource 的 API 的所有怪癖和缺陷。您已经正确指出可以调用$promise 来获取promise 对象,这也是您应该在代码中执行的操作。

这是您的代码的修改版本,其中 createAdmin 返回一个承诺,该承诺在所有子步骤完成后解决:

var createAdmin = function (organization) {
  var newAdmin = {
    name: $scope.organization.admin.name,
    email: $scope.organization.admin.email,
    password: $scope.organization.admin.password,
    organizationId: organization.id
  };

  return Admin.create(newAdmin).$promise
    .then(function login(adminInstance) {
      return AuthService.login({ email: newAdmin.email, password: newAdmin.password });
    })
    .then(function goToDashboard() {
      $state.go('admin.dashboard');
    });
  });
};

【讨论】:

    猜你喜欢
    • 2013-12-23
    • 2016-10-25
    • 2016-09-26
    • 1970-01-01
    • 2018-06-02
    • 2016-07-15
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多