如何在AngularJS中单元测试promise / callback链?

时间:2015-10-21 18:40:59

标签: javascript angularjs unit-testing jasmine loopbackjs

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

以下是我正在创建组织的示例,在完成该请求后,我为组织创建了一个管理员(需要组织的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 promise语法(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变量。

1 个答案:

答案 0 :(得分:0)

  

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

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

以下是代码的修改版本,其中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'); }); }); }; 返回在所有子步骤完成后解析的承诺:

gen = {cost =1000, value=hotdog} //here an example of your data

function changeButtonBC(gen) {
if (money < gen.cost) {
    document.getElementById('buy'+gen.value).className = 'buttongrey';
}
else {
    document.getElementById('buy'+gen.value).className = 'button';
}