import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { FormProvider, useForm } from 'react-hook-form';
import { AreaSelect } from '../../src/components/AreaSelect';
// Mock API客户端
vi.mock('../../src/api/areaClient', () => ({
areaClientManager: {
get: vi.fn(() => ({
index: {
$get: vi.fn(() => Promise.resolve({
status: 200,
json: () => Promise.resolve({
data: [
{ id: 1, name: '北京市', level: 1 },
{ id: 2, name: '上海市', level: 1 }
]
})
}))
}
}))
}
}));
// 测试组件包装器
const TestWrapper = ({ children }: { children: React.ReactNode }) => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});
// 创建一个简单的form context
const methods = useForm();
return (
{children}
);
};
describe('AreaSelect 组件测试', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('应该正确渲染AreaSelect组件', () => {
render(
);
expect(screen.getByText('选择所在省份')).toBeInTheDocument();
expect(screen.getByText('选择所在城市')).toBeInTheDocument();
expect(screen.getByText('选择所在区县')).toBeInTheDocument();
});
it('当required=true时,省份应该显示必填标记,城市和区县不应该显示必填标记(未选择省份时)', () => {
render(
);
// 检查省份标签是否包含星号
const provinceLabel = screen.getByText('省份');
expect(provinceLabel.innerHTML).toContain('*');
// 检查城市标签不应该包含星号(因为还没有选择省份)
const cityLabel = screen.getByText('城市');
expect(cityLabel.innerHTML).not.toContain('*');
// 检查区县标签不应该包含星号
const districtLabel = screen.getByText('区县');
expect(districtLabel.innerHTML).not.toContain('*');
});
it('当required=false时,所有字段都不应该显示必填标记', () => {
render(
);
const provinceLabel = screen.getByText('省份');
expect(provinceLabel.innerHTML).not.toContain('*');
const cityLabel = screen.getByText('城市');
expect(cityLabel.innerHTML).not.toContain('*');
const districtLabel = screen.getByText('区县');
expect(districtLabel.innerHTML).not.toContain('*');
});
it('当选择了城市时,区县字段不应该显示必填标记(即使required=true)', () => {
// 这个测试验证区县字段永远不会显示必填标记
// 即使required=true且选择了城市,区县字段也不应该显示星号
render(
);
// 检查区县标签不应该包含星号
const districtLabel = screen.getByText('区县');
expect(districtLabel.innerHTML).not.toContain('*');
});
it('应该正确处理onChange回调', () => {
const handleChange = vi.fn();
render(
);
// 验证组件渲染正常
expect(screen.getByText('选择所在省份')).toBeInTheDocument();
// onChange会在用户交互时被调用,这里我们只验证组件能接收onChange prop
expect(handleChange).not.toHaveBeenCalled();
});
it('应该支持禁用状态', () => {
render(
);
// 验证组件渲染正常
expect(screen.getByText('选择所在省份')).toBeInTheDocument();
// 禁用状态会在UI中体现,这里我们只验证组件能接收disabled prop
});
it('应该正确处理初始值', () => {
const initialValue = {
provinceId: 1,
cityId: 3,
districtId: 5
};
render(
);
// 验证组件渲染正常 - 查找FormDescription中的文本
expect(screen.getByText('选择所在省份')).toBeInTheDocument();
// 初始值会在组件内部处理,这里我们只验证组件能接收value prop
});
});