Использование fake-indexeddb для интеграционных тестов

fake-indexeddb представляет собой полноценную реализацию API IndexedDB в памяти, предназначенную для использования в средах, где стандартный IndexedDB недоступен, например, при запуске Node.js-тестов. Она совместима с большинством библиотек, работающих с IndexedDB, включая idb-keyval, и позволяет выполнять интеграционные тесты без необходимости задействовать браузер.

Для установки используется npm:

npm install fake-indexeddb

Подключение в тестах выполняется следующим образом:

const FDBFactory = require('fake-indexeddb/lib/FDBFactory');
global.indexedDB = new FDBFactory();

После этого любые вызовы к idb-keyval будут использовать виртуальную базу данных в памяти, полностью имитируя поведение IndexedDB.


Основные функции idb-keyval в тестах

Библиотека idb-keyval предоставляет удобные функции для работы с хранилищем ключ-значение поверх IndexedDB. Основные методы, которые используются в интеграционных тестах:

  • set(key, value, storeName) — сохраняет значение по ключу.
  • get(key, storeName) — получает значение по ключу.
  • del(key, storeName) — удаляет значение по ключу.
  • clear(storeName) — очищает все записи в хранилище.
  • keys(storeName) — возвращает массив всех ключей.
  • upd ate(key, updater, storeName) — обновляет значение по ключу с использованием функции updater.

Пример интеграционного теста с использованием fake-indexeddb:

const { se t, get, del, keys, clear } = require('idb-keyval');

describe('idb-keyval с fake-indexeddb', () => {
    beforeEach(async () => {
        await clear();
    });

    it('должен сохранять и получать значение', async () => {
        await set('user', { name: 'Alice', age: 30 });
        const value = await get('user');
        expect(value).toEqual({ name: 'Alice', age: 30 });
    });

    it('должен удалять значение', async () => {
        await set('temp', 123);
        await del('temp');
        const value = await get('temp');
        expect(value).toBeUndefined();
    });

    it('должен возвращать все ключи', async () => {
        await set('a', 1);
        await set('b', 2);
        const allKeys = await keys();
        expect(allKeys.sort()).toEqual(['a', 'b']);
    });
});

Организация структуры хранилищ для тестов

idb-keyval поддерживает создание и использование нескольких хранилищ (stores). Это позволяет моделировать сложные сценарии, когда приложение использует разные области данных.

Пример использования собственного хранилища:

const { Store, set, get } = require('idb-keyval');

const userStore = new Store('my-database', 'users');

await set('alice', { age: 30 }, userStore);
const alice = await get('alice', userStore);

В тестах это помогает создавать изолированные окружения, где данные одного теста не пересекаются с данными другого.


Симуляция ошибок и особых условий

fake-indexeddb позволяет вручную симулировать ошибки, например, отклонение транзакций, что полезно для проверки устойчивости к ошибкам:

global.indexedDB.open = () => {
    return {
        transaction: () => {
            throw new Error('Сбой транзакции');
        }
    };
};

await expect(set('key', 'value')).rejects.toThrow('Сбой транзакции');

Это даёт возможность тестировать обработку исключений без вмешательства реальной базы данных.


Использование в сочетании с асинхронными тестовыми фреймворками

При работе с Jest, Mocha или другими фреймворками асинхронные функции idb-keyval удобно интегрируются с async/await. Особое внимание уделяется очистке состояния между тестами:

afterEach(async () => {
    await clear();
});

Эта практика предотвращает “загрязнение” данных между тестами и обеспечивает стабильность результатов.


Совместное использование с mock-файловыми хранилищами

В сложных сценариях тестирования можно комбинировать fake-indexeddb с другими mock-объектами для эмуляции взаимодействия с API или локальным хранилищем. Это позволяет создавать комплексные интеграционные тесты, которые полностью воспроизводят поведение приложения в реальной среде, не обращаясь к браузеру.


Рекомендации по производительности

  • Использование fake-indexeddb в Node.js тестах значительно ускоряет выполнение по сравнению с реальным IndexedDB в браузере.
  • При большом объёме данных можно заранее заполнять хранилища в блоке beforeAll, чтобы сократить время подготовки каждого теста.
  • Очистка состояния после каждого теста предотвращает утечки памяти и конфликтные ситуации при параллельном выполнении тестов.

Интеграция с CI/CD

fake-indexeddb идеально подходит для автоматизированного тестирования в CI/CD. Поскольку она полностью работает в памяти и не требует браузера, тестовые сборки остаются лёгкими и быстрыми, а результаты интеграционных тестов стабильными.

Фактически, можно запускать полный набор тестов idb-keyval в Node.js на любом сервере CI без дополнительных настроек окружения.