HTTP responseError拦截器导致$ http错误回调在使用$ httpBackend

时间:2016-10-20 09:46:32

标签: angularjs jasmine karma-jasmine

我正在使用$ httpBackend测试角度服务方法,并尝试根据请求数据模拟不同的响应。问题是,如果我发送错误状态,如果请求无效,它仍然调用$ 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。< / p>

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

  $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);
        });