Unit testing моделей и коллекций

Unit testing является важной частью разработки на Backbone.js, так как обеспечивает стабильность моделей и коллекций при изменениях в коде. Backbone предоставляет простую структуру для организации данных через Models и Collections, а правильное тестирование этих компонентов помогает выявлять ошибки до их попадания в продакшн.


Тестирование моделей

Модель в Backbone.js представляет собой объект данных с атрибутами, методами для их управления и событиями для отслеживания изменений. Основные моменты при тестировании модели:

  1. Создание экземпляра модели
const Book = Backbone.Model.extend({
    defaults: {
        title: '',
        author: '',
        year: null
    }
});

const book = new Book({ title: '1984', author: 'Orwell', year: 1949 });

Тест должен проверять корректность инициализации атрибутов:

describe('Book Model', function() {
    it('should have default values', function() {
        const book = new Book();
        assert.equal(book.get('title'), '');
        assert.equal(book.get('author'), '');
        assert.isNull(book.get('year'));
    });

    it('should set attributes correctly', function() {
        const book = new Book({ title: '1984', author: 'Orwell', year: 1949 });
        assert.equal(book.get('title'), '1984');
        assert.equal(book.get('author'), 'Orwell');
        assert.equal(book.get('year'), 1949);
    });
});
  1. Валидация данных Модели могут содержать метод validate, который проверяет корректность атрибутов перед их установкой. Тестирование валидации позволяет гарантировать целостность данных:
const User = Backbone.Model.extend({
    validate: function(attrs) {
        if (!attrs.username) return 'Username is required';
        if (attrs.age && attrs.age < 0) return 'Age cannot be negative';
    }
});

describe('User Model Validation', function() {
    it('should fail without username', function() {
        const user = new User();
        const error = user.validate({ age: 25 });
        assert.equal(error, 'Username is required');
    });

    it('should fail for negative age', function() {
        const user = new User({ username: 'Alice' });
        const error = user.validate({ age: -5 });
        assert.equal(error, 'Age cannot be negative');
    });
});
  1. Тестирование событий Backbone позволяет подписываться на изменения атрибутов через события change. Unit-тесты должны проверять, что события срабатывают корректно:
it('should trigger change event', function(done) {
    const book = new Book();
    book.on('change:title', function() {
        assert.equal(book.get('title'), 'New Title');
        done();
    });
    book.set('title', 'New Title');
});

Тестирование коллекций

Коллекции (Collections) в Backbone.js представляют собой упорядоченные наборы моделей. Тестирование коллекций включает несколько ключевых аспектов:

  1. Инициализация и добавление моделей
const Books = Backbone.Collection.extend({ model: Book });
const collection = new Books([
    { title: '1984', author: 'Orwell' },
    { title: 'Brave New World', author: 'Huxley' }
]);

describe('Books Collection', function() {
    it('should contain models', function() {
        assert.equal(collection.length, 2);
        assert.equal(collection.at(0).get('title'), '1984');
    });

    it('should add a model', function() {
        collection.add({ title: 'Fahrenheit 451', author: 'Bradbury' });
        assert.equal(collection.length, 3);
        assert.equal(collection.at(2).get('title'), 'Fahrenheit 451');
    });
});
  1. Удаление моделей
it('should remove a model', function() {
    const model = collection.at(0);
    collection.remove(model);
    assert.equal(collection.length, 2);
    assert.notInclude(collection.models, model);
});
  1. События коллекций Коллекции генерируют события при добавлении, удалении и изменении моделей:
it('should trigger add event', function(done) {
    collection.on('add', function(model) {
        assert.equal(model.get('title'), 'Dune');
        done();
    });
    collection.add({ title: 'Dune', author: 'Herbert' });
});

it('should trigger remove event', function(done) {
    const model = collection.at(0);
    collection.on('remove', function(removedModel) {
        assert.equal(removedModel, model);
        done();
    });
    collection.remove(model);
});
  1. Сортировка и фильтрация Коллекции часто имеют методы sort и filter, которые также подлежат тестированию:
const SortedBooks = Backbone.Collection.extend({
    model: Book,
    comparator: 'year'
});

const sortedCollection = new SortedBooks([
    { title: 'Book A', year: 2000 },
    { title: 'Book B', year: 1990 }
]);

it('should sort models by year', function() {
    sortedCollection.sort();
    assert.equal(sortedCollection.at(0).get('year'), 1990);
});

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

  • Использовать Mocha или Jest для структуры тестов и утверждений.
  • Применять Sinon.js для создания шпионов и заглушек событий.
  • Тестировать как положительные, так и отрицательные сценарии, включая валидацию и обработку ошибок.
  • Проверять корректность срабатывания событий для моделей и коллекций.
  • Разделять тесты по функциональности: инициализация, методы, события, валидация, фильтрация и сортировка.

Unit-тестирование моделей и коллекций Backbone.js повышает надежность приложения, снижает количество ошибок и упрощает поддержку кода при масштабировании проекта.