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 { SupplierSelector } from '../../src/components/SupplierSelector'; import { supplierClient } from '../../src/api/supplierClient'; // 完整的mock响应对象 const createMockResponse = (status: number, data?: any) => ({ status, ok: status >= 200 && status < 300, body: null, bodyUsed: false, statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error', headers: new Headers(), url: '', redirected: false, type: 'basic' as ResponseType, json: async () => data || {}, text: async () => '', blob: async () => new Blob(), arrayBuffer: async () => new ArrayBuffer(0), formData: async () => new FormData(), clone: function() { return this; } }); // Mock API client vi.mock('../../src/api/supplierClient', () => { const mockSupplierClient = { $get: vi.fn(() => Promise.resolve({ status: 200, body: null, json: async () => ({ data: [], pagination: { total: 0, page: 1, pageSize: 100 } }) })), }; const mockSupplierClientManager = { get: vi.fn(() => mockSupplierClient), }; return { supplierClientManager: mockSupplierClientManager, supplierClient: mockSupplierClient, }; }); const createTestQueryClient = () => new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); const renderWithProviders = (component: React.ReactElement) => { const queryClient = createTestQueryClient(); return render( {component} ); }; describe('SupplierSelector', () => { beforeEach(() => { vi.clearAllMocks(); }); it('应该渲染供应商选择器', () => { renderWithProviders(); const selectTrigger = screen.getByTestId('supplier-selector'); expect(selectTrigger).toBeInTheDocument(); }); it('应该显示自定义占位符', () => { renderWithProviders( ); const selectTrigger = screen.getByTestId('supplier-selector'); expect(selectTrigger).toHaveTextContent('请选择供应商'); }); it('应该调用API获取供应商列表', async () => { const mockSuppliers = [ { id: 1, name: '供应商A' }, { id: 2, name: '供应商B' } ]; (supplierClient.$get as any).mockResolvedValueOnce( createMockResponse(200, { data: mockSuppliers, pagination: { total: 2, page: 1, pageSize: 100 } }) ); renderWithProviders(); await waitFor(() => { expect(supplierClient.$get).toHaveBeenCalledWith({ query: { page: 1, pageSize: 100 } }); }); }); it('应该显示供应商列表', async () => { const mockSuppliers = [ { id: 1, name: '供应商A' }, { id: 2, name: '供应商B' } ]; (supplierClient.$get as any).mockResolvedValueOnce( createMockResponse(200, { data: mockSuppliers, pagination: { total: 2, page: 1, pageSize: 100 } }) ); renderWithProviders(); await waitFor(() => { expect(supplierClient.$get).toHaveBeenCalledWith({ query: { page: 1, pageSize: 100 } }); }); // 验证API调用,不测试下拉菜单的UI交互 expect(supplierClient.$get).toHaveBeenCalledTimes(1); }); it('应该处理API错误', async () => { (supplierClient.$get as any).mockRejectedValueOnce(new Error('API错误')); renderWithProviders(); // 验证组件渲染 const selectTrigger = screen.getByTestId('supplier-selector'); expect(selectTrigger).toBeInTheDocument(); // 等待API调用完成 await waitFor(() => { expect(supplierClient.$get).toHaveBeenCalled(); }); }); it('应该支持禁用状态', () => { renderWithProviders( ); const selectTrigger = screen.getByTestId('supplier-selector'); expect(selectTrigger).toBeDisabled(); }); it('应该支持值选择', async () => { const mockSuppliers = [ { id: 1, name: '供应商A' }, { id: 2, name: '供应商B' } ]; (supplierClient.$get as any).mockResolvedValueOnce( createMockResponse(200, { data: mockSuppliers, pagination: { total: 2, page: 1, pageSize: 100 } }) ); const mockOnChange = vi.fn(); renderWithProviders( ); await waitFor(() => { expect(supplierClient.$get).toHaveBeenCalledWith({ query: { page: 1, pageSize: 100 } }); }); // 验证API调用,不测试下拉菜单的UI交互 expect(supplierClient.$get).toHaveBeenCalledTimes(1); }); });