Angular 使用 $httpBackend 的测试失败并出现“400 抛出”错误
Angular test using $httpBackend fails with "400 thrown" error
几个小时以来,我一直在尝试使用 $httpBackend 测试我的 NewPostController。问题是每当我在响应中设置非 2xx 状态代码时,测试都会失败。
NewPostController 有以下方法:
$scope.submit = function () {
var newPost = $scope.newPost;
PostService.insertPost(newPost).then(function (post) {
$location.path("/my-posts");
}, function (status) {
$scope.form.$setPristine();
$scope.error = status;
});
};
我在测试故障路径时遇到问题:
it(...) {
...
$scope.post.text = "";
$httpBackend.expectPOST("/create-post", {"post":$scope.post}).respond(400);
$scope.submit();
$httpBackend.flush();
expect($scope.error).toBeDefined();
$scope.post.text = "This is a valid text.";
$httpBackend.expectPOST("/create-post", {"post": $scope.post}).respond(200);
$scope.submit();
$httpBackend.flush();
expect($location.path()).toBe("/my-posts");
});
测试失败并显示消息“400 抛出”(无调用堆栈)。我尝试更改子测试的顺序,使用 whenPOST 而不是 expectPOST 并像在 Angular 文档 (https://docs.angularjs.org/api/ngMock/service/$httpBackend) 中那样组合方法,但没有成功。
请帮忙。
编辑:
现在,当我查看 PostService 时,“400 抛出”的来源很有意义,但我希望 angular 能够处理该错误。我扔是因为this article的"Handling problems in nested service calls"段。它应该是 deferred.resolve/reject 机制的较短版本。
this.insertPost = function (newPost) {
return $http({
method: "post",
url: "/create-post",
data: {
post: newPost
}
}).then(function (res) {
return (res.data);
}, function (res) {
throw res.status;
});
};
这确实很奇怪,也许 angular 团队没有考虑到这一点。
当一个 promise 被抛出拒绝时(就像你正在做的那样),angular $exceptionHandler service 被调用并抛出异常。默认情况下,此服务仅在浏览器控制台中记录异常。
但是当使用 ngMocks 时,this service 被一个可以记录或重新抛出异常的模拟实现所取代。默认模式是rethrow,目的是在抛出异常时让测试失败。
我的建议是避免使用 throw 来简单地拒绝承诺,从而取代
function (res) {
throw res.status;
}
来自
function (res) {
return $q.reject(res.status);
}
但是如果你真的想继续使用throw,你也可以配置mock exceptionHandler来记录而不是重新抛出:
beforeEach(module(function($exceptionHandlerProvider) {
$exceptionHandlerProvider.mode('log');
}));
几个小时以来,我一直在尝试使用 $httpBackend 测试我的 NewPostController。问题是每当我在响应中设置非 2xx 状态代码时,测试都会失败。
NewPostController 有以下方法:
$scope.submit = function () {
var newPost = $scope.newPost;
PostService.insertPost(newPost).then(function (post) {
$location.path("/my-posts");
}, function (status) {
$scope.form.$setPristine();
$scope.error = status;
});
};
我在测试故障路径时遇到问题:
it(...) {
...
$scope.post.text = "";
$httpBackend.expectPOST("/create-post", {"post":$scope.post}).respond(400);
$scope.submit();
$httpBackend.flush();
expect($scope.error).toBeDefined();
$scope.post.text = "This is a valid text.";
$httpBackend.expectPOST("/create-post", {"post": $scope.post}).respond(200);
$scope.submit();
$httpBackend.flush();
expect($location.path()).toBe("/my-posts");
});
测试失败并显示消息“400 抛出”(无调用堆栈)。我尝试更改子测试的顺序,使用 whenPOST 而不是 expectPOST 并像在 Angular 文档 (https://docs.angularjs.org/api/ngMock/service/$httpBackend) 中那样组合方法,但没有成功。
请帮忙。
编辑:
现在,当我查看 PostService 时,“400 抛出”的来源很有意义,但我希望 angular 能够处理该错误。我扔是因为this article的"Handling problems in nested service calls"段。它应该是 deferred.resolve/reject 机制的较短版本。
this.insertPost = function (newPost) {
return $http({
method: "post",
url: "/create-post",
data: {
post: newPost
}
}).then(function (res) {
return (res.data);
}, function (res) {
throw res.status;
});
};
这确实很奇怪,也许 angular 团队没有考虑到这一点。
当一个 promise 被抛出拒绝时(就像你正在做的那样),angular $exceptionHandler service 被调用并抛出异常。默认情况下,此服务仅在浏览器控制台中记录异常。
但是当使用 ngMocks 时,this service 被一个可以记录或重新抛出异常的模拟实现所取代。默认模式是rethrow,目的是在抛出异常时让测试失败。
我的建议是避免使用 throw 来简单地拒绝承诺,从而取代
function (res) {
throw res.status;
}
来自
function (res) {
return $q.reject(res.status);
}
但是如果你真的想继续使用throw,你也可以配置mock exceptionHandler来记录而不是重新抛出:
beforeEach(module(function($exceptionHandlerProvider) {
$exceptionHandlerProvider.mode('log');
}));