Подтвердить что ты не робот

SpyOn метод просмотра позвоночника с использованием жасмина

У меня есть позвоночник, и я хочу создать тест, чтобы подтвердить, что событие click на каком-то элементе вызовет функцию, связанную с этим элементом. Мой взгляд:

PromptView = Backbone.View.extend({
        id:"promptPage",
        attributes:{
            "data-role":"page",
            "data-theme":"a"
        },
        events:{
            "click #btnYes":    "answerYes",
            "tap #btnYes":      "answerYes"
        },
        render: function(){
            $(this.el).html(_.template($('#promptPage-template').html(), this.model.toJSON()));

            return this;
        },
        answerYes: function(){
            alert('yes');
        }
    });

Моя спецификация:

beforeEach(function() {
            model = new PromptModel;
            view = new PromptView({model:model});
            loadFixtures('promptPage.tmpl');
        });

 it("should be able to answer a question with yes", function() {
                var button = $("#btnYes", view.render().el);
                expect(button.length).toBe(1);

                spyOn(view, 'answerYes');

                button.click();
                expect(view.answerYes).toHaveBeenCalled();

            });

Однако приведенное выше определение представления создает метод answerYes в прототипе Прото, но шпион создает функцию в фактическом экземпляре в представлении, поэтому я получаю view.answerYes(), который это шпион и вид.__ proto __. answerYes, который я на самом деле хочу отслеживать.

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

4b9b3361

Ответ 1

Привет, у меня была такая же проблема. И я только что нашел решение, после создания метода spyed (answerYes) вам нужно обновить события представления, чтобы вызвать этот новый метод spyed;):

[...]

    spyOn(view, 'answerYes');
    view.delegateEvents();

    button.click();
    expect(view.answerYes).toHaveBeenCalled();

[...]

Дополнительная информация о событиях делегатов

Удачи!

Ответ 2

Мне обычно нравится предполагать, что код фреймворка уже делает то, что ему нужно, и только проверяет его использование, поэтому я считаю приемлемым проведение теста, проверяющего хеш событий. Если я обнаружил, что дублирую функциональность базы, чтобы проверить мою вещь (например, делегирование событий), то, возможно, я на шаг ближе к интеграционным тестам, чем мне действительно нужно. Я также сильно использую прототип, чтобы быть супер-одинокой леди в моих модульных тестах. Конечно, по-прежнему важно иметь уровень интеграции, который выполняет все это, но я считаю, что цикл обратной связи слишком длинный для фазы тестирования.

Ответ 3

Это создает шпион по методу answerYes PromptView:

spyOn(PromtView.prototype, 'answerYes');

Ответ 4

TL; DR: Шпион по методу экземпляра, а не прототип.

Думаю, вам нужно настроить свой тест по-другому. В блоке it слишком много проблем и слишком много ожиданий, и вы также загрязняете глобальное пространство имен, что может вызвать проблемы с тестами.

beforeEach(function() {
  loadFixtures('promptPage.tmpl');

  var model = new PromptModel();
  this.view = new PromptView({model:model});
  this.view.render();

  this.button = this.view.$("#btnYes");
});

it("should render the button", function(){
  expect(this.button.length).toBe(1);
});

it("should be able to answer a question with yes", function() {
  spyOn(this.view, 'answerYes');

  this.button.click();
  expect(this.view.answerYes).toHaveBeenCalled();
});

Вам не нужно строгое ожидание на длине кнопки. Если кнопка не имеет длины (не найдена), вы получите другие сбои. Но вы можете захотеть, чтобы это стало легче понять, что представление не отображается правильно.

Вы также должны следить за экземпляром view, как вы делали. Определение PromptView добавляет метод answerYes к прототипу, да, но тот, который вы хотите отслеживать, - это экземпляр представления, а не прототип.

Если вы отслеживаете метод прототипа, то каждый раз, когда вы пытаетесь использовать это представление в своих тестах, метод answerYes будет шпионом, а не фактическим методом. Это может показаться приятным, но это вызовет проблемы, так как у вас не будет доступа к действительным данным шпиона при вызове этого метода несколько раз. Он просто накапливает все звонки на одного шпиона. Если вы попытаетесь дважды заглянуть в прототипный метод, вы можете оказаться в шпионах шпиона, что было бы странно и могло бы вызвать проблемы.

Ответ 5

Если у вас возникли проблемы с использованием spyOn, вы можете подумать о создании шпиона. Так что-то вроде:

var eventSpy;
eventSpy = jasmine.createSpy('eventSpy');
view.$el.on('myCustom:event', eventSpy);