2016-09-07 1 views
0

Я тестирую службу, которая использует другую службу для вызовов API, назовем это службой данных. Служба данных тестируется в другом месте, поэтому я отвлек ее простую реализацию, содержащую пустые функции; Я возвращаю данные через отложенный объект и синтаксис spyOn от Jasmine.

Проблема, с которой я нахожу этот подход, - это когда данные возвращаются, это не сразу доступно для вызывающего объекта, как если бы я использовал $ httpBackend. Знаю, что я мог бы просто использовать $ httpBackend, но я хотел бы знать, пропустил ли я что-то (простое или иное) в этом подходе.

Пример секции кода я пытаюсь тест:

storeTheData = dataService.getSomeData(); 
storeTheData.$promise.then(function(data) { 

    /*this would work*/ 
    console.log(data); 

    /*but this would not, when testing using $q*/ 
    _.forEach(storeTheData, function(storedData) { 
     /*do something with each object returned*/ 
    }); 
}); 

Как примечание стороны, я не думаю, что ситуация помогает и ... $ promise.then на другой линии, но в идеале я бы не изменить код (я обеспечиваю тестовое покрытие на что-то писалось давно ...)

Пример теста:

beforeEach(
    ... 
    dataService = { 
     getSomeData: function() { } 
    }; 
    getSomeDataDeferred = $q.defer(); 
    spyOn(dataService, "getSomeData").and.returnValue({$promise: getSomeDataDeferred.promise}); 
    ... 
); 

it(... 
    getSomeDataDeferred.resolve([{obj: "obj1"}, {obj: "obj2"}]); 
    $scope.$apply(); 
    ... 
); 

с тестом, описанным выше, консоль. лог (данные) будет проверяться, поскольку данные доступны из переданного в .then(). Но данные не сразу доступны из storeTheData, поэтому storeTheData [0] .obj не будет определен. При отлаживании я могу увидеть данные, если я воспользуюсь обещанием, которое было прикреплено к storeTheData через storeTheData. $$ state.value

Как я уже сказал, я знаю, что вместо этого могу использовать $ httpBackend, но есть ли способ сделать это с помощью $ q без изменение кода проверки?

ответ

0

Я не нашел способ сделать это с помощью $ q.resolve, но у меня есть решение, которое не включает использование службы данных или изменение тестируемого кода. Это так же хорошо, потому что основные вещи, которые я хотел избежать, - это тестирование службы данных как побочного эффекта и изменение кода.

Мое решение было для создания объекта $ ресурса через $ инжектором ...

$resource = $inject.get("$resource"); 

... затем вернуться, что в моей основной реализации службы данных. Это означает, что я мог бы использовать $ httpBackend для ответа на запрос конечной точки, не зависящей от определения службы данных, остающегося последовательным.

dataService = { 
    getSomeData: function() { 
     /* new code starts here */ 
     var resource = $resource(null, null, { 
      get: { 
       method: "GET", 
       isArray: true, 
       url: "/getSomeData" 
      } 
     }); 

     return resource.get(); 
     /* new code ends here */ 
    } 
}; 
... 
$httpBackend.when("GET", "/getSomeData").respond(...; 
Смежные вопросы