如何使用 httpbackend 测试 Restangular http 调用以测试成功和错误情况?

Posted

技术标签:

【中文标题】如何使用 httpbackend 测试 Restangular http 调用以测试成功和错误情况?【英文标题】:How to Karma test Restangular http call using httpbackend to test both success and error cases? 【发布时间】: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 调用时,我可以同时成功和错误用例

【问题讨论】:

【参考方案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

【讨论】:

谢谢!!完美运行

以上是关于如何使用 httpbackend 测试 Restangular http 调用以测试成功和错误情况?的主要内容,如果未能解决你的问题,请参考以下文章

使用 jasmin 使用带有 async/await 的 $httpBackend 测试角度服务

对指令进行单元测试 - 无法强制使用虚假数据

java Suma Resta Fechas

API测试-PostMan使用

eclipse运行Android项目出现“The connection to adb is down, and a severe error has occured. You must resta

再见了,Postman!HTTP 接口测试工具出现新杀器