2015-07-04 2 views
0

Вот моя фабрика в моем app.jsКак написать тестовый блок для службы, которая возвращает обещание

app.factory('userInfoFacrory', ['$http' , "$q", function($http,$q){ 
    return { 
      getNames:function(){ 
      var differed = $q.defer(); 
      $http.get("http://localhost/ang/api/v1/users/names") 
      .success(function(data) { 
       differed.resolve(data); 
      }).error(function(msg) { 
       differed.reject(msg); 
      }); 
      return differed.promise; 
      } 
    } 
    }]) 

Я использую этот завод в моем контроллере, как сильфон, и она отлично работает:

app.controller('mainController', ['$scope','userInfoFacrory','$log', function($scope,userInfoFacrory,$log){ 

    var promise = userInfoFacrory.getNames(); 
    promise.then(function (data) { 
     $log.info(data); // I get my data correctly here 
    }, function (msg) { 
     $log.error(data); 
    }) 
}]) 

И здесь, я пытался написать тестовый блок, с карма-жасмин

describe('userInfoFacrory', function() { 
var factory ,$rootScope,$scope,$q,onTaskComplete , promise; 

     beforeEach(function() { 
     module("testApp"); 
     inject(function ($injector) { 
      $q = $injector.get("$q"); 
      factory = $injector.get("userInfoFacrory"); 
      $rootScope = $injector.get("$rootScope"); 
      $scope = $rootScope.$new(); 
      promise = factory.getNames(); // this function comes from my factory which returns a promise 
     });  
     }); 

     it('should return a promise', function() { 
      // This test will pass , so no error so far 
     expect(typeof promise.then).toEqual('function'); 
     }); 
}); 

Но я не могу понять, как проверить, так что если мое обещание будет иметь мои данные (которые исходят из моего api) или нет, любое предложение будет оценено.

благодаря

ответ

2
it('should return a promise resolved with the http response data if the http request is successful', inject(function($httpBackend) { 

    var expectedData = 'fake data'; 
    $httpBackend.expectGET('http://localhost/ang/api/v1/users/names').respond(expectedData); 
    var promise = factory.getNames(); 
    var actualData; 
    promise.then(function(result) { 
     actualData = result; 
    }); 
    $httpBackend.flush(); 
    expect(actualData).toEqual(expectedData); 
})); 

it('should return a promise rejected with the http response data if the http request is in error', inject(function($httpBackend) { 

    var expectedData = 'fake data'; 
    $httpBackend.expectGET('http://localhost/ang/api/v1/users/names').respond(400, expectedData); 
    var promise = factory.getNames(); 
    var actualData; 
    promise.catch(function(result) { 
     actualData = result; 
    }); 
    $httpBackend.flush(); 
    expect(actualData).toEqual(expectedData); 
})); 

Рабочие plunkr: http://plnkr.co/edit/NfO6KXWLs1QT5HG8MK0J?p=preview

Обратите внимание, что ваш код правильно, но на самом деле не использовать возможности выстраивания обещаний. Это может быть просто написано, как

getNames: function() { 
    return $http.get("http://localhost/ang/api/v1/users/names") 
     .then(function(response) { 
      return response.data; 
     }, function(response) { 
      return $q.reject(response.data); 
     }); 
    }; 
} 

Работая plunkr: http://plnkr.co/edit/C5x8wRYCQ0wetjozEd0a?p=preview

+0

Ошибка: Неожиданный запрос: GET HTTP: // локальный/анг/API/v1/пользователей/имена \t Нет больше просьба ожидать –

+0

И что точно $ httpBackend здесь? Я имею в виду, что хочу запустить вызов api на моем заводе, чтобы проверить, работает ли он, я не хочу звонить в Api в модульном тесте, –

+0

Вы должны удалить вызов службы внутри beforeEach(). $ httpBackend описывается в документации: https://docs.angularjs.org/api/ngMock/service/$httpBackend –