如何在AngularJS单元测试中使用$ httpBackend注入和模拟$ http?

时间:2018-12-21 18:14:36

标签: angularjs jasmine

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

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对象上使用when代替$httpBackend。我还尝试使用$httpBackend.flush()以确保在发生断言时解决伪造的API调用。

由于断言没有发生,因此测试正在“通过”。我希望断言发生,然后我的测试会增加价值。

2 个答案:

答案 0 :(得分:0)

我相信这应该对您有用

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

答案 1 :(得分:0)

此解决方案应该可以工作,并使用 $ httpBackend whenGET

   describe("httpClientService", function() {
     var httpClientService, exceptionService, $httpBackend;
     var url = 'https://wwww.example.com';

     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');
            spyOn(exceptionService, 'handleError');
          });
       });

       afterEach(function() {
         $httpBackend.verifyNoOutstandingExpectation();
         $httpBackend.verifyNoOutstandingRequest();
       });

       describe("404 response", function() {

         it('logs 404 when no options provided', function() {
           var response = {
             status: 404
           };

           $httpBackend.whenGET(url).respond(404, response);
           $httpBackend.expectGET(url);

           httpClientService.get(url);
           $httpBackend.flush();

           expect(exceptionService.handleError).toHaveBeenCalled();
         });
       });
     });
   });