-1

Итак, я в настоящее время тестирую функцию в AngularJS с Jasmine + Karma. Я пытаюсь создать объект и посмотреть, будет ли он успешно добавлен в базу данных. Эта функция вызывает другую асинхронную функцию, которую я не могу объяснить при тестировании. Я знаю, что это никогда не называется, потому что я ничего не получаю от этого. Нет консольных журналов, ошибок или чего-либо еще. В настоящее время, у меня есть сервис под названием StoringService, который выглядит как:

myApp.service("StoringService", function($http){ 

    // Stores my object 
    this.store = function(object,success,error){ 
     var request = { 
      method: "post", 
      url: "example.com", 
      headers: {/*...*/}, 
      data: object.toJSON() 
     }; 
     $http(request).then(
      function(response){ 
       console.log("Success! Yay!"); 
       success(response.data.url.script); 
      },function(response){ 
       console.log("Error! Bummer..."); 
       error(response); 
      } 
     ); 
    }; 
}); 

Главный контроллер, который я тестирую мой CreationController. У этого есть функция, называемая Submit, которая вызывает вышеупомянутую услугу. Это работает, когда я запускаю свое приложение, но не кажется, когда я запускаю свои тесты. Способ представить (внутри CreationController) выглядит примерно так:

myApp.controller("CreationController", ["$scope","StoringService", 
    function($scope,StoringService){ 

     $scope.newObject = new Object(); 
     $scope.successAlert = false; // changed by success() in StoringService 
     $scope.errorAlert = false; // changed by error() in StoringService 

     $scope.submit = function(){ 
      StoringService.store($scope.newObject, 
       function(message){ 
        console.log(message); 
       }, 
       function(error){ 
        console.log(error); 
       } 
      ); 
     } 
}]); 

Наконец, когда я получил к тестам Жасмин + Карма, я заметил, что мои объекты не были созданы, и при дальнейшем осмотре, что мой StoringService работает до конца текущего запроса $ http (строка 11 в примере кода). Я не совсем уверен, как вызвать это действие. В настоящее время мои тесты похожи.

//creation_test.js 
var scope, service; 

describe('Creation Test', function(){ 
    originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; 

    beforeEach(module('MyApplication')); 
    beforeEach(inject($rootScope, $controller, $injector){ 

     scope = $rootScope.$new(); 
     service = $injector.get('StoringService'); 

     $controller('CreationController',{ 
      $scope: scope, 
      StoringService: service 
     }); 
    })); 

    // Fails but should pass 
    it('should create an object',function(done){ 
     scope.newObject.name = "new_object"; 
     scope.newObject.data = "object data"; 
     scope.submit(); 
     setTimeout(function(){ 
      expect(scope.successAlert).toBe(true); 
      expect(scope.errorAlert).toBe(false); 
      done(); 
     },5000); 
    }); 

    afterEach(function(){ 
     jasmine.DEFAULT_TIMEOUT_INTERVL = originalTimeout; 
    }); 
); 

Я не совсем уверен, почему это не работает или как именно его исправить. Значения для successAlert и errorAlert никогда не изменяются, что заставляет меня думать, что запрос $ http никогда не вызывается. Я пытался использовать возможные решения от here, но до сих пор никто не разрешил проблему. Я бы очень признателен за помощь в решении этой проблемы, и я был бы очень рад, если бы кто-нибудь нашел решение.

+0

Что вы пытаетесь протестировать? Я не вижу 'CreationController', создающего какой-либо объект ... – Puigcerber

+0

Я просто пытаюсь проверить, успешно ли объект добрался до базы данных или нет. Я оставил этот код, потому что не знал, нужно ли это. Но пустой объект будет просто выглядеть как Object {name: "", data: "", timestamp: ""}. Используя форму, пользователь заполнит поля для имени и данных и отправит их в базу данных. –

+0

То, что вы пытаетесь сделать, это тестирование e2e, и это то, что обычно не нужно выполнять в карме. Угловое модульное тестирование предполагает, что реальные запросы не выполняются. Должно быть ** два ** теста - один для блока управления с издеваемым сервисом, другой для сервисного модуля с посмешищем $ http response. Единичные тесты проверяют отдельные единицы, отсюда и название. Они не являются «все-в-одном». – estus

ответ

0

Я подправил свой тест. При тестировании модулей мы не хотим тратить время на вызов бэкэнд, и поэтому нам нужно издеваться над HTTP-вызовами. Поскольку ваш метод store возвращает обещание, мы эмулируем это поведение в модульном тесте, создавая отложенное обещание, которое мы можем контролировать. Позже вы можете resolve или reject обещание проверить успех и ошибку. Я надеюсь, что это помогает.

describe('Controller: CreationController', function() { 

    beforeEach(module('MyApplication')); 

    var storingService; 
    var deferred; 
    // Mock services and spy on methods 
    beforeEach(inject(function($q, StoringService) { 
    deferred = $q.defer(); 
    storingService = StoringService; 
    spyOn(storingService, 'store').and.returnValue(deferred.promise); 
    })); 

    var CreationController; 
    var scope; 
    // Initialize the controller and a mock scope 
    beforeEach(inject($rootScope, $controller) { 
    scope = $rootScope.$new(); 
    CreationController = $controller('CreationController', { 
     $scope: scope, 
     StoringService: storingService 
    }); 
    })); 

    it('should create an object', function() { 
    scope.submit(); 
    scope.$apply(function() { 
     deferred.resolve(); 
    }); 
    expect(scope.successAlert).toBe(true); 
    expect(scope.errorAlert).toBe(false); 
    }); 

); 

 Смежные вопросы

  • Нет связанных вопросов^_^