【问题标题】:HTTP responseError interceptor causing $http error callback to not being called when testing with $httpBackendHTTP responseError 拦截器导致 $http 错误回调在使用 $httpBackend 进行测试时未被调用
【发布时间】:2017-03-02 05:56:06
【问题描述】:

我正在使用 $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 在成功回调中。

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

【问题讨论】:

    标签: angularjs jasmine karma-jasmine


    【解决方案1】:

    我认为您必须在官方文档中查找响应方法签名。 它说 respond 需要一个返回数组的 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);
            });
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2019-02-11
        • 1970-01-01
        • 2020-11-08
        • 2018-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多