
Testing Patterns
Write Jest unit tests with factories and mocks while following TDD red-green-refactor and behavior-focused assertions.
Overview
Testing-patterns is an agent skill most often used in Ship (also Build frontend) that teaches Jest factories, mocking, and TDD red-green-refactor for behavior-focused unit tests.
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill testing-patternsWhat is this skill?
- TDD workflow: failing test first, minimal pass, then refactor—no production code without a failing test
- Behavior-driven rules: test public APIs and requirements, not implementation details
- Factory pattern via getMockX(overrides?: Partial<X>) with sensible defaults for DRY suites
- Custom renderWithTheme wrapper example for React Native Testing Library and provider-heavy components
- Three-step TDD cycle documented: failing test first, minimal pass, refactor after green
Adoption & trust: 775 installs on skills.sh; 40.1k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are shipping features fast but your unit tests are ad hoc, coupled to implementation details, or missing a repeatable factory and TDD habit.
Who is it for?
Indie devs on React Native or Jest stacks who want disciplined unit tests and TDD without reinventing patterns each sprint.
Skip if: Playwright-only E2E suites, load testing, or teams that forbid TDD and only want snapshot dumps of entire apps.
When should I use this skill?
Writing unit tests, creating test factories, or following the TDD red-green-refactor cycle with Jest.
What do I get? / Deliverables
You get consistent Jest test structure, reusable mock factories, provider-aware render helpers, and a TDD loop your agent can apply feature by feature.
- Unit test files with factory helpers
- Custom render utilities
- TDD-ordered test cases
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Automated unit testing and TDD discipline are shelved under Ship because they gate confidence before release, even though tests are written during Build. Testing subphase matches Jest patterns, mocking strategies, and the explicit TDD workflow in the skill body.
Where it fits
Scaffold getMockUser factories and renderWithTheme before merging a new settings screen.
Run red-green-refactor on a billing helper so release branch has failing-then-passing Jest coverage.
Add a regression test for a production bug using behavior-focused naming instead of locking internal hooks.
How it compares
Opinionated Jest/TDD procedural skill—not a hosted test runner, CI MCP, or visual regression service.
Common Questions / FAQ
Who is testing-patterns for?
Solo and small-team developers using Jest (often with React Native Testing Library) who want factories, mocks, and TDD spelled out for their coding agent.
When should I use testing-patterns?
Use it in Ship while hardening releases with unit tests, in Build when scaffolding tests alongside new UI or logic, and in Operate when you add regression tests around bug fixes.
Is testing-patterns safe to install?
It is documentation and code-pattern guidance; review the Security Audits panel on this Prism page and the community source repo before installing bundled skills.
SKILL.md
READMESKILL.md - Testing Patterns
# 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: ```typescript // 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:** ```typescript 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 ```typescript 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 ```typescript 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 ```typescript // 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 ```typescript 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 ```typescript 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 ```typescript // Element must exist expect(screen.getByText('Hello')).toBeTruthy(); // Element should not exist expect(screen.queryByText('Goodbye