code-showcase-testing-patterns – skill Lập trình cho agent AI
Mẫu test Jest, factory function, chiến lược mock và quy trình TDD. Dùng khi viết unit test, tạo test factory hoặc theo chu trình TDD red-green-refactor.
Cài skill code-showcase-testing-patterns bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/code-showcase-testing-patterns-99587.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /code-showcase-testing-patterns – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/code-showcase-testing-patterns-99587.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $code-showcase-testing-patterns – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/code-showcase-testing-patterns-99587.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /code-showcase-testing-patterns – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/code-showcase-testing-patterns-99587.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /code-showcase-testing-patterns – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
Testing Patterns and Utilities
When to Use
Use this skill when you need 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 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: '[email protected]',
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
expect(await 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'), '[email protected]');
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: '[email protected]', role: 'user' };
});
it('test 2', () => {
const user = { id: '2', name: 'Jane', email: '[email protected]' }; // 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.tsxIntegration with Other Skills
- react-ui-patterns: Test all UI states (loading, error, empty, success)
- systematic-debugging: Write test that reproduces bug before fixing
Limitations
- Use this skill only when the task clearly matches its upstream source and local project context.
- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.
- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
Skill liên quan
- code-simplification – Đơn giản hóa code cho dễ hiểu. Dùng khi tái cấu trúc code để rõ ràng hơn mà không đổi…
- code-simplifier – Đơn giản hóa và tinh chỉnh code cho rõ ràng, nhất quán và dễ bảo trì, đồng thời giữ…
- react-native-architecture – Xây dựng ứng dụng React Native production với Expo, navigation, native module, đồng bộ…
- karpathy-coder – Dùng khi viết, review hoặc commit code để áp dụng 4 nguyên tắc code của Karpathy — nêu…
- codebase-cleanup-refactor-clean – Bạn là chuyên gia tái cấu trúc code, chuyên về nguyên tắc clean code, các mẫu thiết kế…
- codebase-cleanup-tech-debt – Xác định nợ kỹ thuật từ code thực tế và lịch sử thay đổi, ước tính tác động và ưu tiên…
- codex-delegate – Giao việc code cho OpenAI Codex CLI chỉ khi người dùng yêu cầu rõ ràng, trong khi…
- codex-profiles – Dùng codex-profiles để chạy Codex CLI hoặc Codex Desktop với các profile CODEX_HOME tách…