3

ПОЛОЖЕНИЕ:Карма-Жасмин: как правильно шпионить за Модалом?

Я Модульное тестирование моего Угловое/Ионное приложения.

У меня проблемы с модальным. На данный момент я могу проверить, что модальный был вызван. Это все до сих пор. Я не могу проверить правильные методы show() и hide() модальности.

Я получаю следующие ошибки:

TypeError: $scope.modal_login.show is not a function 
Error: show() method does not exist 

TypeError: $scope.modal_login.hide is not a function 
Error: hide() method does not exist 

Я думаю, что это полностью зависит от шпиона. Я не знаю, как правильно следить за модальными, и я думаю, что как только это будет сделано, все будет работать нормально.

КОД:

Контроллер:

$scope.open_login_modal = function() 
{ 
    var temp = $ionicModal.fromTemplateUrl('templates/login.html',{scope: $scope}); 

    temp.then(function(modal) { 
     $scope.modal_login = modal; 
     $scope.modal_login.show(); 

     $scope.for_test_only = true; 
    }); 
}; 

$scope.close_login_modal = function() 
{ 
    $scope.modal_login.hide(); 
}; 

Примечание: код функции open_login_modal был переработан, чтобы облегчить испытание. Исходный код был:

$scope.open_login_modal = function() 
{ 
    $ionicModal.fromTemplateUrl('templates/login.html', { 
     scope: $scope 
    }).then(function(modal) { 

     $scope.modal_login = modal; 
     $scope.modal_login.show(); 
    }); 
}; 

тест:

describe('App tests', function() 
{ 
    beforeEach(module('my_app.controllers')); 

    function fakeTemplate() 
    { 
     return { 
      then: function(modal){ 
       $scope.modal_login = modal; 
      } 
     } 
    } 

    beforeEach(inject(function(_$controller_, _$rootScope_) 
    { 
     $controller = _$controller_; 
     $rootScope = _$rootScope_; 
     $scope = _$rootScope_.$new(); 

     $ionicModal = 
     { 
      fromTemplateUrl: jasmine.createSpy('$ionicModal.fromTemplateUrl').and.callFake(fakeTemplate) 
     }; 

     var controller = $controller('MainCtrl', { $scope: $scope, $rootScope: $rootScope, $ionicModal: $ionicModal }); 
    })); 


    describe('Modal tests', function() 
    { 
     beforeEach(function() 
     { 
      $scope.open_login_modal(); 
      spyOn($scope.modal_login, 'show'); // NOT WORKING 
      spyOn($scope.modal_login, 'hide'); // NOT WORKING 
     }); 

     it('should open login modal', function() 
     { 
      expect($ionicModal.fromTemplateUrl).toHaveBeenCalled(); // OK 
      expect($ionicModal.fromTemplateUrl.calls.count()).toBe(1); // OK 
      expect($scope.modal_login.show()).toHaveBeenCalled(); // NOT PASS 
      expect($scope.for_test_only).toEqual(true); // NOT PASS 
     }); 

     it('should close login modal', function() 
     { 
      $scope.close_login_modal();  
      expect($scope.modal_login.hide()).toHaveBeenCalled(); // NOT PASS 
     }); 
    }); 

}); 

Как вы можете видеть из кода $ scope.for_test_only оно должно быть равно верно, но не признается. Вместо этого я получаю это сообщение об ошибке:

Expected undefined to equal true. 

То же самое происходит с методом show() и hide(). Тесты не проверяются.

И я думаю, потому что они не объявлены шпионом.

ВОПРОС:

Как я правильно следить за модальным?

спасибо!

ответ

3

Вопрос здесь может быть экстраполирован на то, как правильно шпионить за обещанием. Вы очень на правильном пути здесь.

Однако, если вы хотите, чтобы проверить, что независимо от вашего обратного вызова для успеха обещания называется, вы должны выполнить два шага:

  1. Mock служба (в вашем случае $ ionicModal) и вернуть некоторые fake function
  2. В этой поддельной функции выполните обратный вызов, который передается вам производственным кодом.

Вот иллюстрация:

//create a mock of the service (step 1) 
var $ionicModal = jasmine.createSpyObj('$ionicModal', ['fromTemplateUrl']); 

//create an example response which just calls your callback (step2) 
var successCallback = { 
    then: function(callback){ 
     callback.apply(arguments); 
    } 
}; 

$ionicModal.fromTemplateUrl.and.returnValue(successCallback); 

Конечно, вы всегда можете использовать $ Q, если вы не хотите, чтобы поддерживать обещание по своему усмотрению:

//in your beforeeach 
var $ionicModal = jasmine.createSpyObj('$ionicModal', ['fromTemplateUrl']); 
//create a mock of the modal you gonna pass and resolve at your fake resolve 
var modalMock = jasmine.createSpyObj('modal', ['show', 'hide']); 
$ionicModal.fromTemplateUrl.and.callFake(function(){ 
    return $q.when(modalMock); 
}); 


//in your test 
//call scope $digest to trigger the angular digest/apply lifecycle 
$scope.$digest(); 
//expect stuff to happen 
expect(modalMock.show).toHaveBeenCalled(); 
+0

О мой Бог! Спасибо! Было так много времени, разбивая голову о стену! Я готов построить статую в твоей честь @ Баба! Также очень хороший ответ, дающий общее правило. Также интересно, что $ scope. $ Digest(); было важно, чтобы все работало. Я буду больше изучать, почему это так. – johnnyfittizio

+2

ха-ха, без проблем, я должен сказать, что я также провел некоторые изнурительные моменты, пытаясь понять это, но я всегда рад помочь. –

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