首页 > 解决方案 > 如何在 AngularJS 单元测试中使用 $httpBackend 注入和模拟 $http?

问题描述

我正在尝试测试以下方法:

function get(url, options) {
    var headers = {
      'X-Request-ID': main.guid(),
      'X-Tenant-ID': tenantId
    };
    if (options.headers) {
      headers = Object.assign(headers, options.headers);
    }
    var responseType = options.responseType || undefined;
    return $http
      .get(url, {headers: headers, responseType: responseType})
      .then(function(response) {
        if (options.transformResponse) {
          options.transformResponse(response);
        }
        return response.data;
      })
      .catch(function(reason) {
        if (options.is404Logged === false && reason.status === 404) {
          return;
        }
        exceptionService.handleError(reason);
      });
  }

这是我的两个测试。我想exceptionService.handleError根据传入的对象测试是否调用了该方法options。换句话说,我正在尝试测试catch上述方法中的块中发生了什么。

describe("httpClientService", function() {
  var httpClientService, exceptionService, $httpBackend;

  beforeEach(function() {
    module("bridge.services");
  });

  describe('get()', function() {
    beforeEach(function() {
      inject(function($injector) {
        httpClientService = $injector.get('httpClientService');
        exceptionService = $injector.get('exceptionService');
        $httpBackend = $injector.get('$httpBackend');
      });
    })

    describe("404 response", function() {
      it('logs 404 when no options provided', function() {
        var url = 'https://wwww.example.com';
        var response = {
          status: 404
        };
        $httpBackend.when('get', url).respond(response);
        spyOn(exceptionService, 'handleError');

        httpClientService
          .get(url)
          .then(function() {
            expect(exceptionService.handleError).toHaveBeenCalled();
          });
      });

      it('does not log 404 when is404Logged is false', function() {
        var url = 'https://wwww.example.com';
        var options = {
          is404Logged: false
        };
        var response = {
          status: 404
        };
        $httpBackend.when('get', url).respond(response);
        spyOn(exceptionService, 'handleError');

        httpClientService
          .get(url, options)
          .then(function() {
            expect(exceptionService.handleError).not.toHaveBeenCalled();
          });
       });
    });
  });
});

由于不清楚的原因,当我运行我的测试时,它根本不执行断言。我可以console.log在块内(在测试中)放置一个语句,then并且没有记录任何内容。无论我断言什么,我的测试都会通过。

我试过在对象上使用whenGET而不是。我还尝试使用以确保在断言发生时解决假 API 调用。when$httpBackend$httpBackend.flush()

测试“通过”,因为断言没有发生。我希望断言发生,然后我的测试将增加价值。

标签: angularjsjasmine

解决方案


我相信这应该对你有用

describe("httpClientService", function() {
  var httpClientService, exceptionService, $httpBackend;

  beforeEach(function() {
    module("bridge.services");
  });

  describe('get()', function() {
    let url = 'https://wwww.example.com';

    beforeEach(function() {
      inject(function($injector) {
        httpClientService = $injector.get('httpClientService');
        exceptionService = $injector.get('exceptionService');
        $httpBackend = $injector.get('$httpBackend');

       spyOn(exceptionService, 'handleError');
      });
    })

    afterEach(() => {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });


    describe("404 response", function() {
      it('logs 404 when no options provided', function() {
        var response = {
          status: 404
        };
        $httpBackend.when('get', url).respond(response);

        httpClientService.get(url);
        $httpBackend.flush();
        expect(exceptionService.handleError).toHaveBeenCalled();
      });

      it('does not log 404 when is404Logged is false', function() {
        var options = {
          is404Logged: false
        };
        var response = {
          status: 404
        };
        $httpBackend.when('get', url).respond(response);

        httpClientService.get(url, options);
        $httpBackend.flush();
        expect(exceptionService.handleError).not.toHaveBeenCalled();
       });
    });
  });
});

推荐阅读