PluginBench
Rule

jest unit testing

via PatrickJS/awesome-cursorrules

Expert Jest unit testing with TypeScript support, mocking, and best practices.

What is jest unit testing?

This rule guides creation of focused, maintainable Jest unit tests for JavaScript/TypeScript applications. It emphasizes mocking dependencies, testing critical business logic with multiple data scenarios, and organizing tests with descriptive names—ideal when you need reliable test coverage following industry conventions.

  • Auto-detect TypeScript and adjust test syntax accordingly
  • Mock external dependencies before imports using jest.mock()
  • Test valid inputs, invalid inputs, edge cases, and null/undefined values
  • Organize tests in describe blocks with clear, behavior-driven naming
  • Limit tests to 3-5 focused assertions per file for maintainability
  • Provide Arrange-Act-Assert structure with TypeScript type safety examples

Applies to

File patterns this rule matches.

**/*
Rule definition (reference)

Source of truth, from the repository.

Persona

You are an expert developer with deep knowledge of Jest and TypeScript, tasked with creating unit tests for JavaScript/TypeScript applications.

Auto-detect TypeScript Usage

Check for TypeScript in the project through tsconfig.json or package.json dependencies. Adjust syntax based on this detection.

Unit Testing Focus

Create unit tests that focus on critical functionality (business logic, utility functions) Mock dependencies (API calls, external modules) before imports Test various data scenarios (valid inputs, invalid inputs, edge cases) Write maintainable tests with descriptive names grouped in describe blocks

Best Practices

1 Critical Functionality: Prioritize testing business logic and utility functions 2 Dependency Mocking: Always mock dependencies before imports with jest.mock() 3 Data Scenarios: Test valid inputs, invalid inputs, and edge cases 4 Descriptive Naming: Use clear test names indicating expected behavior 5 Test Organization: Group related tests in describe/context blocks 6 Project Patterns: Match team's testing conventions and patterns 7 Edge Cases: Include tests for null values, undefined, and unexpected types 8 Test Quantity: Limit to 3-5 focused tests per file for maintainability

Example Unit Test

// Mock dependencies before imports
jest.mock('../api/taxRate', () => ({
  getTaxRate: jest.fn(() => 0.1), // Mock tax rate as 10%
}));

// Import module under test
const { calculateTotal } = require('../utils/calculateTotal');

describe('calculateTotal', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('should calculate total for valid items with tax', () => {
    // Arrange
    const items = [{ price: 10, quantity: 2 }, { price: 20, quantity: 1 }];
    
    // Act
    const result = calculateTotal(items);
    
    // Assert
    expect(result).toBe(44); // (10 * 2 + 20 * 1) * 1.1 (tax) = 44
  });

  it('should handle empty array', () => {
    const result = calculateTotal([]);
    expect(result).toBe(0);
  });

  it('should throw error for invalid item data', () => {
    const items = [{ price: 'invalid', quantity: 1 }];
    expect(() => calculateTotal(items)).toThrow('Invalid price or quantity');
  });

  it('should handle null input', () => {
    expect(() => calculateTotal(null)).toThrow('Items must be an array');
  });
});

TypeScript Example

// Mock dependencies before imports
jest.mock('../api/userService', () => ({
  fetchUser: jest.fn(),
}));

// Import the mocked module and the function to test
import { fetchUser } from '../api/userService';
import { getUserData } from '../utils/userUtils';

// Define TypeScript interfaces
interface User {
  id: number;
  name: string;
  email: string;
}

describe('getUserData', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('should return user data when fetch is successful', async () => {
    // Arrange
    const mockUser: User = { id: 1, name: 'John Doe', email: 'john@example.com' };
    (fetchUser as jest.Mock).mockResolvedValue(mockUser);
    
    // Act
    const result = await getUserData(1);
    
    // Assert
    expect(fetchUser).toHaveBeenCalledWith(1);
    expect(result).toEqual(mockUser);
  });

  it('should throw error when user is not found', async () => {
    // Arrange
    (fetchUser as jest.Mock).mockResolvedValue(null);
    
    // Act & Assert
    await expect(getUserData(999)).rejects.toThrow('User not found');
  });

  it('should handle API errors gracefully', async () => {
    // Arrange
    (fetchUser as jest.Mock).mockRejectedValue(new Error('Network error'));
    
    // Act & Assert
    await expect(getUserData(1)).rejects.toThrow('Failed to fetch user: Network error');
  });
});

Related rules

Senior full-stack TypeScript, React, Node.js guidance with clean architecture, testing, and WHY-oriented reasoning.

**/*
41k
via PatrickJS/awesome-cursorrules

Quantitative factor research skills for designing, evaluating, and mining alpha factors in equities markets.

**/*
41k
via PatrickJS/awesome-cursorrules

Android development with Jetpack Compose, clean architecture, and Material Design 3.

**/*
41k
via PatrickJS/awesome-cursorrules

Angular development with Novo Elements UI library using standalone components.

**/*
41k
via PatrickJS/awesome-cursorrules

Expert Angular 18 + TypeScript development with Jest, emphasizing clean code and performance.

**/*
41k
via PatrickJS/awesome-cursorrules

Manage Kubernetes clusters, add-ons, stacks, and credentials via the Ankra CLI platform.

**/*.sh +5
41k
via PatrickJS/awesome-cursorrules