【问题标题】:How to Karma test Restangular http call using httpbackend to test both success and error cases?如何使用 httpbackend 测试 Restangular http 调用以测试成功和错误情况?
【发布时间】:2017-05-20 15:29:36
【问题描述】:

我正在使用 karma/jasmine 测试 Angular 服务,我的服务功能之一如下。我需要将覆盖率提高到 100%,但似乎无法弄清楚如何测试成功和错误案例。..

function getAccount(accountId) {
   var defer = $q.defer(), myService;
   myService = Restangular.all('Some/Url/Path');
   myService.get('', {}, {
     'header-info': 'bla'
   })
   .then(function onSuccess(response) {
      defer.resolve(response);
   }, function onError() {
      someMethodCall();
   });
   return defer.promise;
}

在我相应的 .spec 测试文件中,我有:

it('should succeed in getting account', function() {
   httpBackend.whenGET('Some/Url/Path').respond(200, mockResponse);
   var promise = myServices.getAccount('account123');
   promise.then(function(response) {
     expect(response).toEqual(mockResponse);
});

it('should error out in getting account', function() {
   httpBackend.whenGET('Some/Url/Path').respond(500, '');
   var promise = myServices.getAccount('account123');
   promise.then(function() {
     expect(someMethodCall).toHaveBeenCalled();
});

现在,两种情况都“通过”,但我没有得到 onError 情况的分支覆盖率。 onSuccess 案例的传递似乎也有些可疑。

基本上我在问什么是正确的语法和编写测试用例的方式,这样当我对我的 API 进行 200 和 500 调用时,我可以同时成功和错误用例

【问题讨论】:

    标签: javascript angularjs karma-jasmine karma-coverage


    【解决方案1】:

    由于您的服务中没有对$http 的任何调用,我建议您模拟Restangular 而不是使用httpBackend。这样你的测试就不需要知道Restangular的实现细节,除了它返回什么,就像你的服务一样。

    模拟示例:

    var Restangular = {
      all: function() {
        return {
          get: function() {
            restangularDeferred = $q.defer();
            return restangularDeferred.promise;
          }
        };
      }
    };
    

    现在您可以轻松解决或拒绝restangularDeferred,具体取决于您要测试的内容。

    设置您的模块以使用模拟:

    module('myApp', function($provide) {
    
      $provide.value('Restangular', Restangular);
    });
    

    成功案例测试示例:

    it('success', function() {
    
      // If you want you can still spy on the mock
      spyOn(Restangular, 'all').and.callThrough();
    
      var mockResponse = {};
    
      var promise = myServices.getAccount('account123');
    
      promise.then(function(response) {
    
        expect(response).toEqual(mockResponse);
        expect(Restangular.all).toHaveBeenCalledWith('Some/Url/Path');
      });
    
      restangularDeferred.resolve(mockResponse);
    
      // Trigger the digest loop and resolution of promise callbacks
      $rootScope.$digest();
    });
    

    错误案例测试示例:

    it('error', function() {
    
      spyOn(anotherService, 'someMethodCall');
    
      var mockResponse = {};
    
      myServices.getAccount('acount123');
    
      restangularDeferred.reject(mockResponse);
    
      $rootScope.$digest();
    
      expect(anotherService.someMethodCall).toHaveBeenCalled();
    });
    

    请注意,我在示例中将someMethodCall 移动到了anotherService

    演示: http://plnkr.co/edit/4JprZPvbN0bYSXFobgmu?p=preview

    【讨论】:

    • 谢谢!!完美运行
    猜你喜欢
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 2017-03-02
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多