Backbone.js просмотр тестов с использованием Sinon Spies в браузере - PullRequest
9 голосов
/ 08 марта 2012

Я пишу тест для Backbone View, чтобы проверить, вызывается ли функция рендеринга после извлечения модели.Тест:

beforeEach(function () {
    $('body').append('<div class="sidebar"></div>');
    profileView = new ProfileView();
});

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

Я использую Sinon Spies для прикрепления объекта-шпиона к функции рендеринга объекта вида profileView.

Вид:

var ProfileView = Backbone.View.extend({
    el: '.sidebar'
  , template: Hogan.compile(ProfileTemplate)
  , model: new UserModel()
  , initialize: function () {
        this.model.bind('change', this.render, this);
        this.model.fetch();
    }
  , render: function () {
        $(this.el).html(this.template.render());
        console.log("Profile Rendered");
        return this;
    }
});

После вызова выборки в тесте запускается событие изменения, и вызывается функция рендеринга представления, но Sinon Spy не обнаруживает, что рендеринг вызывается, и происходит сбой.

КакВ эксперименте я попытался вызвать функцию рендеринга в тесте, чтобы увидеть, опознал ли ее шпион:

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.render();
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

Шпион, обнаруживший, что вызванный был сделан в описанном выше случае.

Кто-нибудь знает, почему шпион не идентифицирует вызов рендеринга в моем первоначальном тесте?

Ответы [ 3 ]

25 голосов
/ 24 апреля 2012

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

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

Чтобы настроить шпиона:

this.renderSpy = sinon.spy(ProfileView.prototype, 'render');
this.view = new ProfileView();

Затем, чтобы удалить шпиона:

ProfileView.prototype.render.restore()

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

3 голосов
/ 14 марта 2012

Всего 3 догадки:

  1. Вы предполагаете, что обратный вызов fetch({ success }) вызывается после того, как Model было обновлено и событие Model сработало ... и, возможно, это не так. Решение : попробуйте воспроизвести отладку вокруг здесь .
  2. Возможно, вызов fetch не success , поэтомуУспешный обратный вызов не называется. Решение : попробуйте добавить ответный сигнал об ошибке к fetch, чтобы увидеть, есть ли там, где мы отправляемся.
  3. Model.validate ответов false,что не очень вероятно , если вы его не реализовали.

(я держу пари на 2. )

0 голосов
/ 28 марта 2012

Это сработало для меня, хотя в коллекции используется шпион:

var thatzzz = this;
    this.hcns.fetch({
        success: function(){
            expect( thatzzz.hcnsFetchSpy ).toHaveBeenCalled();
        }
});
  • шпион был определен до того, как
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...