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

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) или нет, любое предложение будет оценено.

благодаря

Теги:
unit-testing
karma-jasmine
promise
deferred

1 ответ

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 localhost / ang / api / v1 / users / names Больше не ожидается запрос
  • 0
    И что именно $ httpBackend делает здесь? Я имею в виду, я хочу запустить вызов API на своем заводе, чтобы посмотреть, работает ли он, я не хочу вызывать мой API в модульном тесте,
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню