2016-09-21 44 views
0

我正在为调用Promise的作用域函数编写测试,并试图访问在承诺解析后设置的某些作用域属性。用Jasmine调用承诺的测试作用域函数

这基本上是我的控制器功能:

$scope.submitNewForm = function(){ 
    Service.createUser($scope.user).then(function(result){ 
     if (result){ 
      $scope.message = 'success'; 
     } else { 
      $scope.message = 'error'; 
     } 
     $scope.$apply(); 
    }); 
}; 

如果调用范围功能后,我的$scope.message是设置好的我非常想测试。

到目前为止,我已经使用$q.defer()一些测试,但对我缺少什么,我没有成功

beforeEach(inject(function ($controller, $rootScope, _Service_, $q) { 
    scope = $rootScope.$new(); 
    Service= _Service_; 
    deferred = $q.defer(); 
    UserController= $controller('UserController', { 
     $scope: scope 
    }); 
})); 

it('should call Service.createUser and set a message', function(){ 
    spyOn(Service, 'createUser').and.callFake(function() { 
     return deferred.promise; 
    }); 
    scope.submitNewForm(); 
    scope.$digest(); 
    expect(scope.message).toBeDefined(); 
}); 

任何想法?

回答

1

那么你在运行测试时可能会遇到这种错误。

Error on running the test

嗯,这是因为你只是从你ServicecreateUser方法创建的spy返回promise

你能做些什么来解决它? 只需在spy内部执行deferred.rejectdeferred.resolve,即可定义scope.message。类似这样的:

spyOn(Service, 'createUser').and.callFake(function() { 
    deferred.resolve('success'); 
    return deferred.promise; 
}); 

另外还有一件事我想建议。您应该将所有的间谍放在注入服务的beforeEach区块内,并模拟controller对象。这样他们将是可重用的。

UPDATE: 将更改应用到的范围,你可以做这样的事情:

it('should call Service.createUser and set a message', function(){ 
    scope.submitNewForm(); 
    scope.$$postDigest(function(){ 
     scope.$digest(); 
     expect(scope.message).toBeDefined(); 
    }); 
}); 

不知道这是否会工作,但是这是一般完成。

+0

谢谢你的答案Siddharth。我现在得到一个'错误:[$ rootScope:inprog] $ digest已在进行中',这可能是因为我在我的Promise回调中调用'$ scope。$ apply()',当我摆脱它时它就起作用了。但我需要它来应用我认为的变化。有什么想法吗? – adolfosrs