Integration testing

Интеграционное тестирование в Backbone.js направлено на проверку взаимодействия между различными компонентами приложения — моделями, коллекциями, видами и маршрутизаторами. Основная цель — убедиться, что отдельные части работают вместе корректно, передавая данные и события согласно бизнес-логике.


Проверка моделей и коллекций

Модели и коллекции — фундамент Backbone-приложения. В интеграционном тестировании проверяется не только их функциональность, но и взаимодействие:

  • Модели должны корректно изменять состояние при вызове методов set, save, fetch.
  • Коллекции должны правильно обновляться при добавлении, удалении или синхронизации с сервером.

Пример интеграционного теста модели и коллекции:

describe('User and UsersCollection integration', function() {
    var user, users;

    beforeEach(function() {
        user = new User({ id: 1, name: 'Alice' });
        users = new UsersCollection([user]);
    });

    it('должен добавлять нового пользователя в коллекцию и триггерить события', function() {
        var newUser = new User({ id: 2, name: 'Bob' });
        var eventTriggered = false;

        users.on('add', function() { eventTriggered = true; });
        users.add(newUser);

        expect(users.length).toBe(2);
        expect(eventTriggered).toBe(true);
    });
});

Ключевой момент: интеграционный тест проверяет взаимодействие объектов, а не отдельные методы.


Взаимодействие представлений (Views)

Backbone.View управляет отображением и реагирует на события модели и коллекции. Интеграционные тесты проверяют синхронизацию состояния данных с DOM:

  • Подключение модели к виду и проверка обновления DOM при изменении данных.
  • Обработка пользовательских событий (клик, ввод) и соответствующая реакция модели.

Пример:

describe('UserView integration with User model', function() {
    var user, view;

    beforeEach(function() {
        user = new User({ name: 'Alice' });
        view = new UserView({ model: user });
        view.render();
    });

    it('обновляет DOM при изменении модели', function() {
        user.set('name', 'Bob');
        expect(view.$el.text()).toContain('Bob');
    });

    it('обрабатывает клик и меняет модель', function() {
        view.$('button.change-name').click();
        expect(user.get('name')).toBe('Charlie');
    });
});

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


Тестирование маршрутизаторов (Routers) и навигации

Маршрутизаторы Backbone обеспечивают навигацию и синхронизацию URL с состоянием приложения. Тестирование включает проверку:

  • Корректного вызова обработчиков при смене маршрута.
  • Взаимодействия маршрутов с моделями и видами.

Пример интеграционного теста маршрутизатора:

describe('AppRouter integration', function() {
    var router, user, view;

    beforeEach(function() {
        user = new User({ name: 'Alice' });
        view = new UserView({ model: user });
        router = new AppRouter({ userView: view });
        Backbone.history.start({ silent: true });
    });

    afterEach(function() {
        Backbone.history.stop();
    });

    it('отображает вид пользователя при переходе на #user', function() {
        router.navigate('user', { trigger: true });
        expect($('#app').html()).toContain('Alice');
    });
});

Особенность: маршрутизатор тесно связан с DOM и моделями, поэтому интеграционное тестирование требует запуска Backbone.history.


Синхронизация с сервером

Backbone.js поддерживает синхронизацию через Backbone.sync. В интеграционных тестах важно проверять:

  • Корректную отправку AJAX-запросов.
  • Правильное обновление моделей и коллекций после ответа сервера.
  • Обработку ошибок и fallback-логики.

Пример с использованием моков AJAX:

describe('User sync integration', function() {
    beforeEach(function() {
        jasmine.Ajax.install();
    });

    afterEach(function() {
        jasmine.Ajax.uninstall();
    });

    it('должен сохранять модель и обновлять коллекцию', function() {
        var user = new User({ name: 'Alice' });
        var users = new UsersCollection();

        user.save();
        var request = jasmine.Ajax.requests.mostRecent();
        request.respondWith({
            status: 200,
            responseText: JSON.stringify({ id: 1, name: 'Alice' })
        });

        users.add(user);
        expect(users.length).toBe(1);
        expect(users.at(0).get('id')).toBe(1);
    });
});

Практические рекомендации

  1. Использовать реальные объекты моделей, коллекций и видов, избегая чрезмерного мокирования, чтобы проверять реальные сценарии.
  2. Фокусироваться на событиях и их цепочках, так как Backbone активно использует событийную архитектуру.
  3. Поддерживать чистоту DOM между тестами, чтобы избежать пересечений состояния.
  4. Разделять интеграционные и unit-тесты: unit-тест проверяет отдельный метод, интеграционный — работу компонентов вместе.

Интеграционное тестирование в Backbone.js обеспечивает уверенность, что приложение работает как единое целое, правильно обрабатывает данные, события и взаимодействует с сервером.