Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Validating Data with Yup and Testing Schemas Using Jest

Tech May 13 3

When building forms or handling user input, robust validation is essential. Instead of writing custom logic for every field, leveraging a schema-based validation library like Yup streamlines the process and improves maintainability.

Yup allows defining schemas that describe expected data structures, including required fields, type constraints, value ranges, and conditional logic. For example:

import { object, string, number, boolean } from 'yup';

const userSchema = object({
  name: string().required(),
  age: number().min(18).max(120).required(),
  country: string().oneOf(['US', 'DE', 'JP']).required(),
  newsletter: boolean().default(false),
});

This schema enforces that name and age are present, age falls within a valid range, and country matches one of the allowed values.

To support dynamic enums—such as those loaded from an API or environment-dependent options—the schema must be constructed at runtime. Since Yup schemas are immutable, updating parts of a schema requires creating a new instance using .shape():

const baseSchema = object({
  name: string().required(),
});

// Dynamically extend based on runtime data
const fullSchema = baseSchema.shape({
  role: string().oneOf(availableRoles).required(),
});

Testing these schemas ensures correctness under various conditions. Jest integrates well for this purpose. A typical test validates both valid inputs and edge cases that should fail:

import { userSchema } from './schema';

describe('User Schema Validation', () => {
  it('accepts valid input', async () => {
    const validData = {
      name: 'Alice',
      age: 30,
      country: 'DE',
      newsletter: true,
    };
    await expect(userSchema.validate(validData)).resolves.toEqual(validData);
  });

  it('rejects age below minimum', async () => {
    const invalidData = {
      name: 'Bob',
      age: 15,
      country: 'US',
    };
    await expect(userSchema.validate(invalidData)).rejects.toThrow();
  });

  it('rejects invalid country code', async () => {
    const invalidData = {
      name: 'Charlie',
      age: 25,
      country: 'XX',
    };
    await expect(userSchema.validate(invalidData)).rejects.toThrow();
  });
});

For dynamic enum values sourced from a function (e.g., getAllowedRoles()), mocking that function in tests allows verifying different configurations:

jest.mock('./roles', () => ({
  getAllowedRoles: jest.fn(),
}));

it('validates against mocked roles', async () => {
  const mockRoles = ['admin', 'user'];
  (getAllowedRoles as jest.Mock).mockReturnValue(mockRoles);

  const dynamicSchema = baseSchema.shape({
    role: string().oneOf(mockRoles).required(),
  });

  await expect(dynamicSchema.validate({ name: 'Test', role: 'admin' })).resolves.not.toThrow();
  await expect(dynamicSchema.validate({ name: 'Test', role: 'guest' })).rejects.toThrow();
});

This approach decouples validation logic from UI components, enables reuse across insert and update operations (with optional fields handled via .nullable() or conditional rules), and ensures reliability through automated tests.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.