Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jasmine支持在返回承诺后运行的测试方法逻辑_Javascript_Angularjs_Asynchronous_Jasmine - Fatal编程技术网

Javascript Jasmine支持在返回承诺后运行的测试方法逻辑

Javascript Jasmine支持在返回承诺后运行的测试方法逻辑,javascript,angularjs,asynchronous,jasmine,Javascript,Angularjs,Asynchronous,Jasmine,我有一个java脚本方法要测试。看起来像这样这是简化的psudocode,请原谅拼写错误 $scope.savePerson = function(){ Person.create($scope.person).then(function(newPerson){ if($scope.person.org){ Organization.addPerson($scope.person.org, newPerson.id);

我有一个java脚本方法要测试。看起来像这样这是简化的psudocode,请原谅拼写错误

$scope.savePerson = function(){
      Person.create($scope.person).then(function(newPerson){
          if($scope.person.org){
             Organization.addPerson($scope.person.org, newPerson.id);
          }

     toaster.pop('success', "person added");
}
这是使用restanglar,但其思想很简单。调用savePerson方法时,它首先保存person对象,保存完成后,如果设置了organization,则会尝试将此人保存到组织中。只有在找到人员后才能保存组织

我想通过为个人和组织创建间谍来测试这种逻辑,然后期望它们都被调用。天真的方法可能看起来像这样:

describe( 'save person', function () {
var Person, Organization, person;


beforeEach(inject(function($controller, $q, _Organization_, _Person_) {
   Person=_Person_;
   Organization=_Organization_;
   person={...} //whaver goes here, but include an org

   Person.create=jasmine.createSpy('create()').andCallFake( funciton(newPerson){
       var defer = $q.defer();
       defer.resolve(personParam);
       return defer.promise;
  });

  Organization.addPerson= jasmine.createSpy('addPerson()').andCallFake(funciton(personParam){
     var defer=$q.defer();
     defer.resolve(personParam);
     return defer.promise;
  });

 controllerOptions.Person=Person;
 controllerOptions.Organization=Organization;
 controllerOptions.person=person;
 MyController= $controller('MyController', controllerOptions);
}));

it('adds org if exists', function(){
   $scope.savePerson($scope.person);

  expect(Person.create).toHaveBeenCalled();
  expect(Organization.addPerson).toHaveBeenCalled();
});
这将失败,特别是不会调用addPerson。这不是代码中的缺陷,而是线程问题。因为我的代码调用了。然后在person.create上,它正在创建一个异步线程来运行。在异步线程启动并运行then逻辑之前,不会调用Organization.addPerson。问题是我的测试在不等待线程的情况下继续运行,因此它到达expect调用并失败

现在,一个非常懒惰的解决方案是在我的测试中添加一个10毫秒的短等待。此测试等待异步线程启动的那一刻,将立即获得响应,并调用addPerson。然而,这是基于中断将如何发生的假设,对于测试来说不够严格

我相信我也可以通过让我的origination.addPerson函数设置一些addPersonCalled值,然后在设置addPersonCalled方法后使用该值来解决这个问题,但它看起来有点难看


这似乎是一个常见的用例。我想知道jasmine是否有更干净的方法来支持这个用例?有没有办法告诉jasmine等待任何电流。然后方法要求您承诺在继续测试之前解决问题?

我们有两种选择。第一种方法是调用$timeout.flush或$rootScope.apply,这将解析所有承诺

然而,这解决了所有的承诺,这成为我测试的一个问题,因为我有我还不想解决的承诺。这部分是由于一些丑陋的黑客绕过一个遗留程序的问题,该程序正在移动到完全删除

另一个看起来很不错的工具…有希望的双关语不是有意的,诚实的!是模拟承诺:

不幸的是,我还没有使用这个工具,但它看起来是一个很好的工具