The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
Development · SKILL.md

testing-patterns

testing-patterns

Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle.

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill documentation

GitHub

name: testing-patterns description: "Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle."

Testing Patterns

Purpose

Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle.

This skill provides operational guidance for Testing Patterns, including tool usage patterns, workflows, and quality expectations aligned with Syncolab skill standards.

When to Use

  • Use when the user needs help with Testing Patterns.
  • When integrations for this domain are available and the task matches the workflows below.

When NOT to Use

  • When the task is unrelated to Testing Patterns or covered by a more specific skill.
  • When required integrations or credentials are unavailable.

Expected Outcome

  • Correct use of domain tools with verified results (not fabricated).
  • Clear summary of actions taken, data returned, and recommended next steps.
  • Errors and missing permissions reported explicitly.

Inputs to Gather

  • User goal, constraints, and any identifiers (URLs, IDs, project keys).
  • Available tool sets and connection status.
  • Relevant context from related systems before destructive writes.

Workflow

  1. Confirm the request maps to Testing Patterns and required tools are available.
  2. Gather identifiers and scope (project, channel, repo, date range, etc.).
  3. Follow the domain guidance below; prefer list/search before get/update when applicable.
  4. Execute tool calls using schemas from the integration; never invent tool output.
  5. Summarize results and offer logical follow-ups.

Testing Patterns and Utilities

Testing Philosophy

Test-Driven Development (TDD):

  • Write failing test FIRST
  • Implement minimal code to pass
  • Refactor after green
  • Never write production code without a failing test

Behavior-Driven Testing:

  • Test behavior, not implementation
  • Focus on public APIs and business requirements
  • Avoid testing implementation details
  • Use descriptive test names that describe behavior

Factory Pattern:

  • Create getMockX(overrides?: Partial<X>) functions
  • Provide sensible defaults
  • Allow overriding specific properties
  • Keep tests DRY and maintainable

Test Utilities

Custom Render Function

Create a custom render that wraps components with required providers:

// src/utils/testUtils.tsx
import { render } from '@testing-library/react-native';
import { ThemeProvider } from './theme';

export const renderWithTheme = (ui: React.ReactElement) => {
  return render(
    <ThemeProvider>{ui}</ThemeProvider>
  );
};

Usage:

import { renderWithTheme } from 'utils/testUtils';
import { screen } from '@testing-library/react-native';

it('should render component', () => {
  renderWithTheme(<MyComponent />);
  expect(screen.getByText('Hello')).toBeTruthy();
});

Factory Pattern

Component Props Factory

import { ComponentProps } from 'react';

const getMockMyComponentProps = (
  overrides?: Partial<ComponentProps<typeof MyComponent>>
) => {
  return {
    title: 'Default Title',
    count: 0,
    onPress: jest.fn(),
    isLoading: false,
    ...overrides,
  };
};

// Usage in tests
it('should render with custom title', () => {
  const props = getMockMyComponentProps({ title: 'Custom Title' });
  renderWithTheme(<MyComponent {...props} />);
  expect(screen.getByText('Custom Title')).toBeTruthy();
});

Data Factory

interface User {
  id: string;
  name: string;
  email: string;
  role: 'admin' | 'user';
}

const getMockUser = (overrides?: Partial<User>): User => {
  return {
    id: '123',
    name: 'John Doe',
    email: 'john@example.com',
    role: 'user',
    ...overrides,
  };
};

// Usage
it('should display admin badge for admin users', () => {
  const user = getMockUser({ role: 'admin' });
  renderWithTheme(<UserCard user={user} />);
  expect(screen.getByText('Admin')).toBeTruthy();
});

Mocking Patterns

Mocking Modules

// Mock entire module
jest.mock('utils/analytics');

// Mock with factory function
jest.mock('utils/analytics', () => ({
  Analytics: {
    logEvent: jest.fn(),
  },
}));

// Access mock in test
const mockLogEvent = jest.requireMock('utils/analytics').Analytics.logEvent;

Mocking GraphQL Hooks

jest.mock('./GetItems.generated', () => ({
  useGetItemsQuery: jest.fn(),
}));

const mockUseGetItemsQuery = jest.requireMock(
  './GetItems.generated'
).useGetItemsQuery as jest.Mock;

// In test
mockUseGetItemsQuery.mockReturnValue({
  data: { items: [] },
  loading: false,
  error: undefined,
});

Test Structure

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

  describe('Rendering', () => {
    it('should render component with default props', () => {});
    it('should render loading state when loading', () => {});
  });

  describe('User interactions', () => {
    it('should call onPress when button is clicked', async () => {});
  });

  describe('Edge cases', () => {
    it('should handle empty data gracefully', () => {});
  });
});

Query Patterns

// Element must exist
expect(screen.getByText('Hello')).toBeTruthy();

// Element should not exist
expect(screen.queryByText('Goodbye')).toBeNull();

// Element appears asynchronously
await waitFor(() => {
  expect(screen.findByText('Loaded')).toBeTruthy();
});

User Interaction Patterns

import { fireEvent, screen } from '@testing-library/react-native';

it('should submit form on button click', async () => {
  const onSubmit = jest.fn();
  renderWithTheme(<LoginForm onSubmit={onSubmit} />);

  fireEvent.changeText(screen.getByLabelText('Email'), 'user@example.com');
  fireEvent.changeText(screen.getByLabelText('Password'), 'password123');
  fireEvent.press(screen.getByTestId('login-button'));

  await waitFor(() => {
    expect(onSubmit).toHaveBeenCalled();
  });
});

Anti-Patterns to Avoid

Testing Mock Behavior Instead of Real Behavior

// Bad - testing the mock
expect(mockFetchData).toHaveBeenCalled();

// Good - testing actual behavior
expect(screen.getByText('John Doe')).toBeTruthy();

Not Using Factories

// Bad - duplicated, inconsistent test data
it('test 1', () => {
  const user = { id: '1', name: 'John', email: 'john@test.com', role: 'user' };
});
it('test 2', () => {
  const user = { id: '2', name: 'Jane', email: 'jane@test.com' }; // Missing role!
});

// Good - reusable factory
const user = getMockUser({ name: 'Custom Name' });

Best Practices

  1. Always use factory functions for props and data
  2. Test behavior, not implementation
  3. Use descriptive test names
  4. Organize with describe blocks
  5. Clear mocks between tests
  6. Keep tests focused - one behavior per test

Running Tests

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Run specific file
npm test ComponentName.test.tsx

Integration with Other Skills

  • react-ui-patterns: Test all UI states (loading, error, empty, success)
  • systematic-debugging: Write test that reproduces bug before fixing

Tool Availability Rules

AccessBehavior
Full tool accessExecute workflows, verify outputs, report errors.
Read-onlyInspect and plan; provide exact commands or dispatch request for writes.
No integrationState limitation; do not fabricate API results.

Related tool sets

  • cypress
  • playwright
  • selenium

Review / Decision / Execution Criteria

  • Prefer smallest safe change; confirm destructive actions with the user.
  • Use evidence from tool responses; cite IDs and links when present.
  • Match integration-specific conventions (JQL, RFC3339, A1 notation, etc.).

Output Format

Report:

  1. What was requested and what was done.
  2. Key results (tables or bullets).
  3. Errors, blockers, or missing permissions.
  4. Suggested next steps.

Quality Bar

  • Specific, actionable, and grounded in tool output.
  • Concise unless the user asked for detail.
  • Respect rate limits, pagination, and API semantics.

Safety and Boundaries

  • Do not commit secrets, tokens, or PII into skills or user-visible logs.
  • Do not fabricate validation, send, or write confirmations.
  • Confirm destructive operations (delete, destroy, mass update) when appropriate.

Escalation / Dispatch Rules

  • If the task spans multiple domains, use or suggest related skills via relationships.skills.
  • If write access is required but unavailable, dispatch or ask the user to enable tools.

References

  • Legacy content migrated from skills/old_skills.json (testing-patterns).
  • skills/skill.instruction.md, skills/meta.instructions.md
Saved skills