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

如何在AngularJS单元测试中使用$httpBackend注入并模拟$http?,angularjs,jasmine,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 = opt

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

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
语句放入
中,然后
块(在测试中)中,不会记录任何内容。不管我断言什么,我的测试都通过了

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


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

我相信这对您应该有用

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

此解决方案应能正常工作,并使用$httpBackend和whenGET:


谢谢你。我的错误是在调用
.respond()
时没有将状态代码指定为它自己的参数。这管用!
   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();
         });
       });
     });
   });