Уничтожить Backbone.Router и все побочные эффекты после создания

Допустим, вы хотите иметь возможность создать экземпляр Backbone.Router, который вызывает Backbone.history.start, уничтожить все его следы и создать его снова.

Мне нужно сделать это для модульного тестирования.

Проблема в том, что создание магистрального маршрутизатора имеет глобальные последствия. Как Backbone.history, который не определен, пока вы не сделаете это.

var ReversibleRouter = Backbone.Router.extend({
  initialize: function(){
    _buildAppPaths(this.options) // Implementation not shown. Builds the application paths
    Backbone.history.start()
  },
  destroy: function(){
    // TODO: Implement this
  }
})

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

Достаточно позвонить Backbone.history.stop() и установить Backbone.history = undefined?

2 ответа

Решение

Если вы хотите выполнить более сложные типы интеграции стека, вы можете сбросить настройки маршрутизатора вашего приложения, используя:

Backbone.history.stop()
Backbone.history = undefined // Could also probably use delete here :)

До сих пор это было успешно - наши тесты, вероятно, запускали и убивали маршрутизатор 5 раз во время нашего qunit тестирования. Работает отлично.

Может быть, издевательство, как говорит @AdamTerlson, - лучший способ работать в долгосрочной перспективе, но я все еще изучаю философию юнит-тестирования и интеграционного тестирования. Хотя я не против провести полный стек или два теста.

Это может быть обманом, но я считаю, что вы должны подделывать функции за пределами вашей функциональной единицы, которую вы тестируете, и особенно быть уверенным, что вашим юнит-тестам не разрешено попадать в действующий DOM, сервер или браузер.

Посмотрите в SinonJS, это здорово для этого.

Вот пример тестирования метода инициализации маршрутизатора без какого-либо влияния на состояние истории браузера.

test('...', function () {
    // Arrange
    var buildAppPaths = sinon.stub(ReversibleRouter.prototype, '_buildAppPaths');
    var startHistory = sinon.stub(Backbone.history, 'start');
    var options = {};

    // Act
    new ReversibleRouter(options);

    // Assert
    ok(buildAppPaths.calledWith(options));
    ok(startHistory.calledOnce); // or ok(Backbone.history.start.calledOnce);
});

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

Для выполнения вызовов за пределами этого одного устройства будут выполняться интеграционные тесты, а не модульные тесты.

Другие вопросы по тегам