Javascript Jasmine支持在返回承诺后运行的测试方法逻辑
我有一个java脚本方法要测试。看起来像这样这是简化的psudocode,请原谅拼写错误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);
$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,这将解析所有承诺 然而,这解决了所有的承诺,这成为我测试的一个问题,因为我有我还不想解决的承诺。这部分是由于一些丑陋的黑客绕过一个遗留程序的问题,该程序正在移动到完全删除 另一个看起来很不错的工具…有希望的双关语不是有意的,诚实的!是模拟承诺: 不幸的是,我还没有使用这个工具,但它看起来是一个很好的工具