HTTP responseError拦截器导致$ HTTP错误回调不被调用时,测试$httpBackend



我正在用$httpBackend测试一个angular服务方法,并试图根据请求数据模拟不同的响应。问题是,如果我发送错误状态,如果请求无效,它仍然调用$http方法的成功回调,因此我无法测试错误情况。服务如下:

app.service('dataService', function($http) {
    var self = this;
    this.getData = function (request) {
        return $http({
            method: 'POST',
            url: 'https://some-url/',
            data: request
        }).then(function successCallback(response) {
            self.valid = true;
            self.data = response.data;
        }, function errorCallback(response) {
            self.valid = false
        });
    };
});
下面是测试代码:
describe('.getData()', function() {
    beforeEach(inject(function(_dataService_, _$httpBackend_) {
        var dataService = _dataService_,
            $httpBackend = _$httpBackend_;
        $httpBackend.when('POST', 'http://some-url/', 'valid request')
            .respond(200, 'data');
        $httpBackend.when('POST', 'http://some-url/', 'invalid request')
            .respond(500, '');
    }));
    // runs successfully
    it('should store data correctly', function() {
        dataService.getData('valid request').then(
            function success(){
                expect(dataService.data).toEqual('data');
            }
        );
        $httpBackend.flush();
    });
    // TypeError: Cannot read property 'data' of undefined
    // This error comes in service at successCallBack() line "self.data = response.data;"
    it('should result in error if any', function() {
        dataService.getData('invalid request').then(
            function success(){
                expect(dataService.valid).toEqual(false);
            }
        );
        $httpBackend.flush();        
    });
});

正如我分析的那样,这是因为HTTP responseError拦截器导致的。如果我删除了拦截器,那么测试代码就可以正常工作(成功和错误回调会根据响应状态被正确调用)。但是一旦我使用responseError拦截器,它就会"吞噬"错误并导致successCallback()被调用,并将response设置为undefined内成功回调。

这种情况下的解决方案是什么?在这种情况下,我们如何测试成功和错误情况?

我的错,我没有从responseError HTTP拦截器返回拒绝。返回拒绝(return $q.reject('Error'))解决了问题。

我认为您必须在官方文档中查找响应方法签名。它说 response 期望一个返回数组的函数类型的参数:

  $httpBackend.whenRoute('GET', '/users/:id')
  .respond(function(method, url, data, headers, params) {
    return [200, MockUserList[Number(params.id)]];
  });

在这段代码中,我返回成功,但我认为错误(500)也是如此:

...  
 beforeEach(angular.mock.inject(function (ApprovalRule, $httpBackend, $http) {
        ...
        this.withOKEntities = function() {
                var i1 = new ApprovalRule();
                i1.id = 10;
                return [200, JSON.stringify([ i1]), {}];
        } ...
    }));
...
it('should resolve to list of approvalrules', function () {
            this.httpBackend.whenGET(new RegExp('.*/api/approvalrules/')).respond(this.withOKEntities);
            var result = this.sut.getAll();
            result.then(this.OnResponse.readResult);
            this.httpBackend.flush();
            expect(check.array.of.instance(this.OnResponse.result, this.ApprovalRule)).toBe(true);
        });

最新更新