> Как проверять разные наборы полей одного класса при десериализации JSON в тестах (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: LeanSoftwareProduction

Стек: JavaScript

> Пример ответа

Короткий ответ

Для проверки разных наборов полей одного класса при десериализации JSON в тестах используйте параметризованные тесты с фабриками данных или отдельные тест-кейсы на каждый вариант. Основной подход - строить минимальный валидный JSON для каждого сценария, а затем проверять только релевантные поля. Это позволяет изолировать поведение десериализатора и избежать дублирования кода через вспомогательные функции генерации тестовых объектов.

Подробное объяснение

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

Основные стратегии:

  1. Параметризация через фабрики - создаёте функцию, которая принимает переопределения полей и возвращает полный объект. В тестах передаёте только нужные поля.

  2. Табличные тесты - описываете массив кейсов с входным JSON и ожидаемым результатом, затем прогоняете через цикл.

  3. Тест на каждый сценарий - для небольших наборов полей пишете отдельные тесты с явными названиями.

Ключевой момент - не проверять весь объект целиком, а использовать expect.objectContaining или проверять только значимые поля. Это делает тесты устойчивыми к добавлению новых полей.

Для сложных случаев (вложенные объекты, массивы) стоит использовать отдельные фабрики для каждого уровня вложенности.

На практике

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

Также учитывайте, что при работе с TypeScript полезно использовать Partial<T> для типизации переопределений в фабриках.

Пример кода

TYPESCRIPT
// Класс для десериализации
class User {
constructor(
public id: number,
public name: string,
public email?: string,
public phone?: string
) {}
static fromJSON(json: any): User {
return new User(
json.id,
json.name,
json.email,
json.phone
);
}
}
// Фабрика для тестов
function createUserJSON(overrides: Partial<User> = {}): any {
return {
id: 1,
name: 'John',
email: 'john@example.com',
phone: '+123456789',
...overrides
};
}
// Параметризованные тесты
describe('User.fromJSON', () => {
const cases = [
{
name: 'без email',
json: createUserJSON({ email: undefined }),
expected: { id: 1, name: 'John', email: undefined, phone: '+123456789' }
},
{
name: 'без phone',
json: createUserJSON({ phone: undefined }),
expected: { id: 1, name: 'John', email: 'john@example.com', phone: undefined }
},
{
name: 'только обязательные поля',
json: createUserJSON({ email: undefined, phone: undefined }),
expected: { id: 1, name: 'John', email: undefined, phone: undefined }
}
];
test.each(cases)('$name', ({ json, expected }) => {
const user = User.fromJSON(json);
expect(user).toEqual(expect.objectContaining(expected));
});
test('полный набор полей', () => {
const user = User.fromJSON(createUserJSON());
expect(user).toEqual({
id: 1,
name: 'John',
email: 'john@example.com',
phone: '+123456789'
});
});
});

Как отвечать на собеседовании

Начните с краткого описания проблемы - разные наборы полей при десериализации. Затем перечислите основные подходы: фабрики, параметризация, отдельные тесты. Объясните, почему важно проверять только релевантные поля, а не весь объект. Приведите пример из практики, если есть. Упомяните trade-off между читаемостью и количеством кода - для простых случаев достаточно отдельных тестов, для сложных - параметризация.

Что проверяет интервьюер

  • Понимание принципов тестирования: изоляция, читаемость, устойчивость к изменениям.
  • Умение проектировать тестовые данные без дублирования.
  • Знание возможностей Jest/Vitest (test.each, expect.objectContaining).
  • Способность объяснить выбор подхода под конкретную ситуацию.

Типичные ошибки

  • Проверка всего объекта целиком - тесты ломаются при добавлении новых полей.
  • Дублирование JSON в каждом тесте - сложно поддерживать.
  • Игнорирование опциональных полей - пропуск важных сценариев.
  • Слишком сложные фабрики с множеством параметров - тесты становятся нечитаемыми.
  • Отсутствие теста на полный набор полей - базовая проверка обязательна.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью