![](/img/trans.png)
[英]Unit testing $q promise within Angular service - Karma, Jasmine
[英]Conditionally resolve or reject $q promise, unit testing with Jasmine
我在下面有一个模拟的服务personService,它正在由我正在测试的控制器personController调用。
我想明显地测试通过/失败路径,因此我试图根据测试中的输入有条件地路由承诺解决/拒绝,以测试两个路径。
// Mocking personService and its functions
beforeEach(inject(function($q) {
personService = {
addPerson: function (resolve) {
var deferred = $q.defer();
if(resolve) {
deferred.resolve();
}
else {
deferred.reject();
}
return deferred.promise;
}
};
// And add its spies
spyOn(personService, 'addPerson').and.callThrough();
}));
// Mocking $state
beforeEach(inject(function () {
$state = {
go: function () {
return true;
}
};
// And its spies
spyOn($state, 'go').and.callThrough();
}));
对于此特定功能,如果对addPerson的服务调用已解决,则将调用$ state.go;如果拒绝了该调用,则不会调用$ state.go,因此,我将进行如下测试:
it("on return error from personService.add, state.go not called", function () {
$scope.addPerson(false);
$rootScope.$digest();
expect($state.go).not.toHaveBeenCalled();
});
it("on return success from personService.add, state.go called", function () {
$scope.addPerson(true);
$rootScope.$digest();
expect($state.go).toHaveBeenCalled();
});
在第一个测试中,我传递的是false,它应该拒绝承诺,而不是调用$ state.go ... ...但是,当实际运行测试时,间谍将在$ state.go上调用!
作为参考,有问题的控制器功能如下:
var _addPerson = function () {
personService.addPerson().then(function (response) {
$state.go('home.person', { personIndex: $scope.personList.length }, { reload: true });
_gotoLastPerson();
}),
function (err) {
console.log(err);
};
};
令人困惑的注解表明我已经关闭...如果我从addPerson中删除if / then,并且始终只是deferred.reject(),则第一个测试通过,第二个测试失败; 如果我总是deferred.resolve(),则会发生完全相反的情况。
1)如何在Jasmine模拟服务调用中使用条件$ q解析/拒绝
更新资料
在搜索之后,似乎有人将所有这些设置本身放入了it()块中,在这种情况下,我可以根据所处的it()更改服务以显式地解析或拒绝...但是这看起来很可怕编码惯例。
万岁! 好的,所以我不知道为什么会这样,但是addPerson: function (resolve)
中的addPerson: function (resolve)
实际上是person对象,而不是布尔值。
因此,我改为创建了一个全局var resolvePromise,根据我的需要将其设置为true / false,并且效果很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.