# 测试模式与工具
## 测试哲学
**测试驱动开发 (TDD):**
- 先写失败的测试
- 实现最少代码以通过
- 绿灯后重构
- 没有失败的测试,绝不编写生产代码
**行为驱动测试:**
- 测试行为,而非实现
- 关注公共 API 和业务需求
- 避免测试实现细节
- 使用描述行为的描述性测试名称
**工厂模式:**
- 创建 `getMockX(overrides?: Partial)` 函数
- 提供合理的默认值
- 允许覆盖特定属性
- 保持测试 DRY(不重复)且易于维护
## 测试工具
### 自定义渲染函数
创建一个自定义渲染函数,用所需的 Provider 包装组件:
typescript
// src/utils/testUtils.tsx
import { render } from '@testing-library/react-native';
import { ThemeProvider } from './theme';
export const renderWithTheme = (ui: React.ReactElement) => {
return render(
{ui}
);
};
**用法:**
typescript
import { renderWithTheme } from 'utils/testUtils';
import { screen } from '@testing-library/react-native';
it('应该渲染组件', () => {
renderWithTheme();
expect(screen.getByText('Hello')).toBeTruthy();
});
## 工厂模式
### 组件 Props 工厂
typescript
import { ComponentProps } from 'react';
const getMockMyComponentProps = (
overrides?: Partial<ComponentProps>
) => {
return {
title: '默认标题',
count: 0,
onPress: jest.fn(),
isLoading: false,
...overrides,
};
};
// 在测试中使用
it('应该使用自定义标题渲染', () => {
const props = getMockMyComponentProps({ title: '自定义标题' });
renderWithTheme();
expect(screen.getByText('自定义标题')).toBeTruthy();
});
### 数据工厂
typescript
interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user';
}
const getMockUser = (overrides?: Partial): User => {
return {
id: '123',
name: 'John Doe',
email: '
[email protected]',
role: 'user',
...overrides,
};
};
// 用法
it('应该为管理员用户显示管理员徽章', () => {
const user = getMockUser({ role: 'admin' });
renderWithTheme();
expect(screen.getByText('Admin')).toBeTruthy();
});
## Mock 模式
### Mock 模块
typescript
// Mock 整个模块
jest.mock('utils/analytics');
// 使用工厂函数进行 Mock