Невозможно использовать сброс httpBackend для ngMockE2E

Я пытаюсь проверить свой контроллер с помощью jasmine. По сути, когда контроллер создается, он вызывает службу для выполнения http-запроса. Я использую httpBackend для получения поддельных данных. Когда я пытаюсь запустить тест, я всегда получаю сообщение об ошибке «Нет ожидающих запросов на сброс». Если я удалю httpBackend.flush(), то тест завершится неудачно, потому что имя контроллера.data.name не определено. Может кто знает почему так происходит? Спасибо.

Код модуля находится здесь:

var myModule = angular.module('myModule', ['ngMockE2E']);
myModule.run(function($httpBackend){
  $httpBackend.whenGET('/Person?content=Manager').respond(function (){
     var response = {'name':'Bob','age':'43'}
     return [200,response];
  })
});

Код для услуги:

myModule.factory('myService',function($http){
     return {
        getData: function(position){
             return  $http.get('/Person?content='+position); 
        }
     }
});

Код для контроллера:

myModule.controller('myController',function(xrefService){
    var _this = this;
    _this.data ={};
    _this.getData = function(position){
        myService.getData(position).then(function(response){
            _this.data = response.data
        });
    }
    _this.getData("Manager");
})

Код для проверки контроллера:

describe("Test Controller",function(){
   var controller,httpBackend,createController;
   beforeEach(module('myModule'));
   beforeEach(inject(function($controller,$httpBackend){      
      createController = function(){
         return $controller('myController');
      }
      httpBackend = $httpBackend;     
   }));
   it("should return data",function(){
      controller = createController();
      httpBackend.flush();
      expect(controller.data.name).toEqual("Bob");
   });      
})

person Steven    schedule 05.04.2016    source источник


Ответы (2)


вы используете $httpBackend.whenGET внутри "Код модуля"

вы должны использовать $httpBackend внутри тестового кода следующим образом...

it("should return data",function(){
  $httpBackend.expectGET('/Person?content=Manager').respond(function (){
      var response = {'name':'Bob','age':'43'}
      return [200,response];
  })
  controller = createController();
  httpBackend.flush();
  expect(controller.data.name).toEqual("Bob");
});      

также я бы посоветовал использовать expectGET вместо whenGET.

С помощью whenGET вы говорите, что если запрос сделан, то ответ будет таким.

С помощью expectGET вы говорите... будет сделан запрос, когда он будет сделан, ответьте так, если запрос не сделан, то не пройдите тест.

PS, если вы поместите некоторые операторы console.log в код вашего контроллера, вы должны увидеть эти операторы журнала при запуске набора тестов. Если нет, то вы знаете, что код вашего контроллера даже не срабатывает.

тоже пользуюсь..

afterEach(function () {
      httpBackend.verifyNoOutstandingExpectation();
      httpBackend.verifyNoOutstandingRequest();
});

что приведет к провалу теста, если ожидания не оправдались.

person danday74    schedule 05.04.2016
comment
Спасибо danday74, теперь все работает. Однако мне интересно, есть ли возможность избежать использования expectGET().respond() в тестовом методе. Так как это означает, что мне нужно прочитать сервисный код, чтобы протестировать контроллер. Например, может быть, я просто хочу проверить, не пуст ли файл controller.data (что означает, что он получает некоторые данные из бэкэнда). - person Steven; 07.04.2016
comment
теперь ты думаешь :) да, ты хочешь использовать шпиона Жасмин. ng-learn.org/2014/08/Testing_Promises_with_Jasmine_Provide_Spy. - person danday74; 07.04.2016
comment
spyOn(myService, 'getData').and.callFake(function() { var def = $q.defer(); def.resolve(YOUR_MOCK_HTTP_RESPONSE); return def.promise; }); ожидать(myService.getData).toHaveBeenCalled(); - person danday74; 07.04.2016
comment
код говорит... когда вызывается myService.getData(), ответьте фальшивым ответом. Поддельный ответ возвращает обещание точно так же, как ваш реальный метод возвращает обещание. Затем вы можете следить за своей сервисной функцией, чтобы увидеть, сколько раз она вызывалась, с какими параметрами она вызывалась и т. д. вы можете продолжать проверять значение в controller.data no probs — теперь оно будет заполнено фальшивыми данными, которые вы предоставьте в своем ответе fak. Боже благослови :) Забыл упомянуть, что ваш настоящий HTTP теперь не будет вызываться, поэтому вам больше не нужно ожидать GET. - person danday74; 07.04.2016
comment
Спасибо danday74, это действительно помогает. :D - person Steven; 08.04.2016

В документации по angular говорится следующее о $httpbackend для ngMockE2E:

Кроме того, мы не хотим вручную сбрасывать имитированные запросы, как мы это делаем во время модульного тестирования. По этой причине e2e $httpBackend автоматически сбрасывает имитированные запросы, точно имитируя поведение объекта XMLHttpRequest.

Итак, короткий ответ: его не существует и он вам не нужен.

person ngstschr    schedule 09.02.2017