Receber por email
← Voltar para o catálogo

jest-testing

Automatically activated when user works with Jest tests, mentions Jest configuration, asks about Jest matchers/mocks, or has files matching *.test.js, *.test.ts, jest.config.*. Provides Jest-specific expertise for testing React, Node.js, and JavaScript applications. Also applies to Vitest due to API compatibility. Does NOT handle general quality analysis - use analyzing-test-quality for that.

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/jest-testing-aiskillstore/svg)](https://www.skillteca.com.br/skills/jest-testing-aiskillstore)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Jest Testing Expertise

You are an expert in Jest testing framework with deep knowledge of its configuration, matchers, mocks, and best practices for testing JavaScript and TypeScript applications.

Your Capabilities

  1. Jest Configuration: Setup, configuration files, environments, and presets
  2. Matchers & Assertions: Built-in and custom matchers, asymmetric matchers
  3. Mocking: Mock functions, modules, timers, and external dependencies
  4. Snapshot Testing: Inline and external snapshots, snapshot updates
  5. Code Coverage: Coverage configuration, thresholds, and reports
  6. Test Organization: Describe blocks, hooks, test filtering
  7. React Testing: Testing React components with Jest DOM and RTL

When to Use This Skill

Claude should automatically invoke this skill when:

  • The user mentions Jest, jest.config, or Jest-specific features
  • Files matching .test.js, .test.ts, .test.jsx, .test.tsx are encountered
  • The user asks about mocking, snapshots, or Jest matchers
  • The conversation involves testing React, Node.js, or JavaScript apps
  • Jest configuration or setup is discussed

How to Use This Skill

Accessing Resources

Use {baseDir} to reference files in this skill directory:

  • Scripts: {baseDir}/scripts/
  • Documentation: {baseDir}/references/
  • Templates: {baseDir}/assets/

Progressive Discovery

  1. Start with core Jest expertise
  2. Reference specific documentation as needed
  3. Provide code examples from templates

Available Resources

This skill includes ready-to-use resources in {baseDir}:

  • references/jest-cheatsheet.md - Quick reference for matchers, mocks, async patterns, and CLI commands
  • assets/test-file.template.ts - Complete test templates for unit tests, async tests, class tests, mock tests, React components, and hooks
  • scripts/check-jest-setup.sh - Validates Jest configuration and dependencies

Jest Best Practices

Test Structure

describe('ComponentName', () => {
  beforeEach(() => {
    // Setup
  });

  afterEach(() => {
    // Cleanup
  });

  describe('method or behavior', () => {
    it('should do expected thing when condition', () => {
      // Arrange
      // Act
      // Assert
    });
  });
});

Mocking Patterns

Mock Functions

const mockFn = jest.fn();
mockFn.mockReturnValue('value');
mockFn.mockResolvedValue('async value');
mockFn.mockImplementation((arg) => arg * 2);

Mock Modules

jest.mock('./module', () => ({
  func: jest.fn().mockReturnValue('mocked'),
}));

Mock Timers

jest.useFakeTimers();
jest.advanceTimersByTime(1000);
jest.runAllTimers();

Common Matchers

expect(value).toBe(expected);          // Strict equality
expect(value).toEqual(expected);       // Deep equality
expect(value).toBeTruthy();            // Truthy
expect(value).toContain(item);         // Array/string contains
expect(fn).toHaveBeenCalledWith(args); // Function called with
expect(value).toMatchSnapshot();       // Snapshot
expect(fn).toThrow(error);             // Throws

Async Testing

// Promises
it('async test', async () => {
  await expect(asyncFn()).resolves.toBe('value');
});

// Callbacks
it('callback test', (done) => {
  callbackFn((result) => {
    expect(result).toBe('value');
    done();
  });
});

Jest Configuration

Basic Configuration

// jest.config.js
module.exports = {
  testEnvironment: 'node', // or 'jsdom'
  roots: ['<rootDir>/src'],
  testMatch: ['**/__tests__/**/*.ts', '**/*.test.ts'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
};

React Testing Library

Setup with Custom Render

// test-utils.tsx
import { render, RenderOptions } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter } from 'react-router-dom';

const AllProviders = ({ children }: { children: React.ReactNode }) => {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });

  return (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>
        {children}
      </BrowserRouter>
    </QueryClientProvider>
  );
};

export const renderWithProviders = (
  ui: React.ReactElement,
  options?: RenderOptions
) => render(ui, { wrapper: AllProviders, ...options });

export * from '@testing-library/react';

Query Priority (Best to Worst)

// 1. Accessible queries (best)
screen.getByRole('button', { name: 'Submit' });
screen.getByLabelText('Email');
screen.getByPlaceholderText('Enter email');
screen.getByText('Welcome');

// 2. Semantic queries
screen.getByAltText('Profile picture');
screen.getByTitle('Close');

// 3. Test IDs (last resort)
screen.getByTestId('submit-button');

User Interactions

import userEvent from '@testing-library/user-event';

test('form submission', async () => {
  const user = userEvent.setup();
  render(<LoginForm />);

  // Type in inputs
  await user.type(screen.getByLabelText('Email'), 'test@example.com');
  await user.type(screen.getByLabelText('Password'), 'password123');

  // Click button
  await user.click(screen.getByRole('button', { name: 'Sign in' }));

  // Check result
  await waitFor(() => {
    expect(screen.getByText('Welcome!')).toBeInTheDocument();
  });
});

test('keyboard navigation', async () => {
  const user = userEvent.setup();
  render(<Form />);

  await user.tab(); // Focus first element
  await user.keyboard('{Enter}'); // Press enter
  await user.keyboard('[ShiftLeft>][Tab][/ShiftLeft]'); // Shift+Tab
});

Testing Hooks

import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';

test('useCounter increments', () => {
  const { result } = renderHook(() => useCounter());

  expect(result.current.count).toBe(0);

  act(() => {
    result.current.increment();
  });

  expect(result.current.count).toBe(1);
});

// With wrapper for context
test('hook with context', () => {
  const wrapper = ({ children }) => (
    <ThemeProvider theme="dark">{children}</ThemeProvider>
  );

  const { result } = renderHook(() => useTheme(), { wrapper });
  expect(result.current.theme).toBe('dark');
});

Async Assertions

import { waitFor, waitForElementToBeRemoved } from '@testing-library/react';

test('async loading', async () => {
  render(<DataFetcher />);

  // Wait for loading to disappear
  await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));

  // Wait for content
  await waitFor(() => {
    expect(screen.getByText('Data loaded')).toBeInTheDocument();
  });

  // With timeout
  await waitFor(
    () => expect(screen.getByText('Slow content')).toBeInTheDocument(),
    { timeout: 5000 }
  );
});

Network Mocking with MSW

Setup

// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
  http.get('/api/users', () => {
    return HttpResponse.json([
      { id: 1, name: 'John' },
      { id: 2, name: 'Jane' },
    ]);
  }),

  http.post('/api/users', async ({ request }) => {
    const body = await request.json();
    return HttpResponse.json({ id: 3, ...body }, { status: 201 });
  }),

  http.delete('/api/users/:id', ({ params }) => {
    return HttpResponse.json({ deleted: params.id });
  }),
];

// src/mocks/server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

Jest Setup

// jest.setup.ts
import { server } from './src/mocks/server';

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
after
Compartilhar X LinkedIn