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

时间:2017-01-05 22:41:57

标签: javascript angularjs karma-jasmine karma-coverage

我正在使用karma / jasmine测试角度服务,我的一个服务功能如下。我需要覆盖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 个答案:

答案 0 :(得分:2)

由于您的服务中没有对$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