Мокирование Cache Storage API

Workbox предоставляет удобный интерфейс для взаимодействия с Cache Storage API, позволяя создавать, управлять и обслуживать кэшированные ресурсы в Service Worker. Ключевой объект — это caches, который позволяет хранить статические и динамические ресурсы для ускорения загрузки и работы приложения в офлайн-режиме.

import {precacheAndRoute} fr om 'workbox-precaching';

// Предварительное кэширование файлов
precacheAndRoute(self.__WB_MANIFEST);

В этом примере precacheAndRoute автоматически создает кэшированные версии файлов, перечисленных в манифесте сборки. Это обеспечивает немедленный доступ к ресурсам без необходимости обращения к сети.

Мокирование Cache Storage API

Мокирование необходимо для тестирования поведения кэшей без реального взаимодействия с браузером. В Workbox это достигается с помощью создания собственных реализаций кэшей и методов, которые имитируют стандартное API.

Создание мок-кэша

class MockCache {
  constructor() {
    this.store = new Map();
  }

  async match(request) {
    return this.store.get(request.url) || null;
  }

  async put(request, response) {
    this.store.set(request.url, response.clone());
  }

  async delete(request) {
    return this.store.delete(request.url);
  }

  async keys() {
    return Array.from(this.store.keys());
  }
}

В этой реализации ключом выступает URL запроса, а значением — клонированный объект ответа. Такой подход позволяет точно эмулировать поведение настоящего Cache API в контролируемой среде.

Подмена стандартного кэша в тестах

Для тестирования Service Worker и стратегий Workbox можно подменять глобальный объект caches на мок-версию:

global.caches = {
  open: async (cacheName) => new MockCache(),
  has: async () => true,
  delete: async () => true,
  keys: async () => ['mock-cache']
};

После этого вызовы Workbox для кэширования или поиска ресурсов будут направляться в мок-объект. Это позволяет проводить unit-тестирование стратегий без необходимости сетевого соединения и реального кэша браузера.

Мокирование стратегий Workbox

Workbox предоставляет множество предустановленных стратегий (CacheFirst, NetworkFirst, StaleWhileRevalidate). Для проверки их поведения можно интегрировать мок-кэш следующим образом:

import {CacheFirst} fr om 'workbox-strategies';

const strategy = new CacheFirst({
  cacheName: 'test-cache',
  plugins: [
    {
      cacheDidUpdate: async ({cacheName, request, oldResponse, newResponse}) => {
        console.log(`Resource upd ated in ${cacheName}: ${request.url}`);
      }
    }
  ]
});

// Пример запроса через стратегию
async function fetchResource(url) {
  const response = await strategy.handle({request: new Request(url)});
  return response ? await response.text() : null;
}

Мокирование кэша позволяет:

  • Проверять, правильно ли стратегия сохраняет ресурсы.
  • Контролировать вызовы плагинов и события обновления.
  • Эмулировать поведение сетевых ошибок или отсутствия ресурса.

Советы по тестированию с мок-Cache Storage

  1. Изолированное состояние: каждый тест должен использовать новый экземпляр мок-кэша, чтобы избежать побочных эффектов.
  2. Эмуляция ошибок: можно создавать методы match и put, которые выбрасывают ошибки, чтобы проверить обработку исключений.
  3. Интеграция с Jest или Mocha: использование глобального подменного объекта caches позволяет писать чистые unit-тесты для Service Worker.
  4. Логирование действий: внедрение плагинов Workbox или простых колбэков для фиксации всех операций с кэшем облегчает отладку.

Примеры продвинутого мокирования

  • Эмуляция истечения срока жизни кэша:
class ExpiringMockCache extends MockCache {
  constructor(expirationTimeMs) {
    super();
    this.expirationTimeMs = expirationTimeMs;
    this.timestamps = new Map();
  }

  async put(request, response) {
    super.put(request, response);
    this.timestamps.se t(request.url, Date.now());
  }

  async match(request) {
    const timestamp = this.timestamps.get(request.url);
    if (timestamp && (Date.now() - timestamp) > this.expirationTimeMs) {
      this.store.delete(request.url);
      this.timestamps.delete(request.url);
      return null;
    }
    return super.match(request);
  }
}
  • Эмуляция ограничения размера кэша:
class SizeLimitedMockCache extends MockCache {
  constructor(lim it) {
    super();
    this.lim it = limit;
  }

  async put(request, response) {
    if (this.store.size >= this.limit) {
      const firstKey = this.store.keys().next().value;
      this.store.delete(firstKey);
    }
    super.put(request, response);
  }
}

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


Мокирование Cache Storage API в Workbox обеспечивает высокую точность тестирования стратегий кэширования, имитацию поведения Service Worker и полное управление ресурсами без необходимости реального сетевого доступа. Оно становится ключевым инструментом при разработке офлайн-функциональности и надежных PWA.