Жасмин шпионам не звонят

У меня возникли проблемы с шпионажем в Жасмин

Я хочу проверить, была ли нажата ссылка на слайдере, используя jasmine spy и jasmine jquery.

Вот упрощенная версия:

У меня есть несколько ссылок как часть файла приспособления html.

<a href="#" class="someLink">Link 1</a>
<a href="#" class="someLink">Link 2</a>

слайдер:

var Slider = function(links){
    this.sliderLinks = $(links);
    this.bindEvents();
}

Slider.prototype.bindEvents = function(){
    this.sliderLinks.on('click', this.handleClick);
}

Slider.prototype.handleClick = function(e){
    console.log('i have been clicked')
}

файл спецификации:

describe('Slider', function(){
    var slider;

    beforeEach(function(){
        loadFixtures('slider.html');

        slider = new Slider('.someLink');

    });

    it('should handle link click', function(){
        spyOn(slider, 'handleClick');
        $(slider.sliderLinks[0]).trigger('click');
        expect(slider.handleClick).toHaveBeenCalled();
    });

});

Тест провален. Но «я был нажат» был зарегистрирован в консоли, поэтому метод вызывается.

Если я сделаю это, тест пройдет:

it('should handle link click', function(){
        spyon(slider, 'handleClick');
        slider.handleClick();
        expect(slider.handleClick).toHaveBeenCalled();
    });

Итак, мой вопрос по существу:

  1. Я неправильно тестирую этот тип вещей?
  2. почему шпион не регистрирует факт вызова метода?

person jamie holliday    schedule 26.07.2013    source источник
comment
Думаю, в этом случае вам следует подсмотреть прототип: spyOn(Slider.prototype, 'handleClick') и поместить этот код перед Slider созданием new Slider(...) (как прокомментировал @EliranMalka). Вы пробовали это?   -  person zbynour    schedule 26.07.2013


Ответы (1)


Я только что проверил решение, изложенное в комментарии. Ваш describe должен быть:

describe('Slider', function () {

    var slider;

    beforeEach(function () {
        loadFixtures('slider.html');
        spyOn(Slider.prototype, 'handleClick');
        slider = new Slider('.someLink');
    });

    it('should handle link click', function (){
        $(slider.sliderLinks[0]).trigger('click');
        expect(slider.handleClick).toHaveBeenCalled();
    });

});

Дело в том, что вы должны шпионить за прототипом функции handleClick и перед созданием Slider.

Причина в том, что Jasmine spyOn действительно делает в предоставленном вами коде:

spyOn(slider, 'handleClick');

создает свойство слайдера handleClick (содержащее шпионский объект) непосредственно в экземпляре slider. slider.hasOwnProperty('handleClick') в этом случае возвращает true, знаете ли...

Но все же есть свойство прототипа handleClick, к которому привязано ваше событие клика. Это означает, что только что инициированное событие щелчка обрабатывается функцией прототипа handleClick, в то время как собственное свойство объекта ползунка handleClick (ваш шпион) остается нетронутым.

Таким образом, ответ заключается в том, что шпион не регистрирует факт вызова метода, потому что он никогда не вызывался :-)

person zbynour    schedule 29.07.2013
comment
+1 ваше объяснение прототипа и собственного свойства точное и нигде не упоминается в документах. большое спасибо! - person dbrin; 23.05.2014
comment
@dbrin Рад помочь =) - person zbynour; 23.05.2014