|
|
@@ -1,7 +1,7 @@
|
|
|
import React from 'react';
|
|
|
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 { QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
|
|
|
import { toast } from 'sonner';
|
|
|
|
|
|
// Mock dependencies
|
|
|
@@ -24,20 +24,40 @@ vi.mock('lucide-react', async () => {
|
|
|
};
|
|
|
});
|
|
|
|
|
|
-// Mock axios to prevent actual network requests
|
|
|
-vi.mock('axios', async () => {
|
|
|
- const actual = await vi.importActual('axios');
|
|
|
+// 创建模拟的rpcClient函数(根据API模拟规范)
|
|
|
+// 符合测试策略文档的API模拟规范:统一模拟@d8d/shared-ui-components/utils/hc中的rpcClient函数
|
|
|
+const mockRpcClient = vi.hoisted(() => vi.fn((aptBaseUrl: string) => {
|
|
|
+ // 根据页面组件实际调用的RPC路径定义模拟端点
|
|
|
+ // 符合规范:支持Hono风格的$get、$post、$put、$delete方法
|
|
|
return {
|
|
|
- ...actual,
|
|
|
- request: vi.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- data: { data: [], total: 0 },
|
|
|
- headers: {},
|
|
|
- config: {},
|
|
|
- statusText: 'OK'
|
|
|
- }))
|
|
|
+ index: {
|
|
|
+ $get: vi.fn(() => Promise.resolve(createMockResponse(200, { data: [], total: 0 }))),
|
|
|
+ $post: vi.fn(() => Promise.resolve(createMockResponse(201))),
|
|
|
+ },
|
|
|
+ ':id': {
|
|
|
+ children: {
|
|
|
+ $get: vi.fn(() => Promise.resolve(createMockResponse(200, { data: [], total: 0 }))),
|
|
|
+ },
|
|
|
+ setAsParent: {
|
|
|
+ $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
+ },
|
|
|
+ parent: {
|
|
|
+ $delete: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
+ },
|
|
|
+ $delete: vi.fn(() => Promise.resolve(createMockResponse(204))),
|
|
|
+ $get: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 123, spuId: 0, tenantId: 1 }))),
|
|
|
+ },
|
|
|
+ batchCreateChildren: {
|
|
|
+ $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
+ },
|
|
|
};
|
|
|
-});
|
|
|
+}));
|
|
|
+
|
|
|
+// 模拟共享UI组件包中的rpcClient函数(统一模拟点)
|
|
|
+// 核心API模拟规范:统一拦截所有API调用,支持跨UI包集成测试
|
|
|
+vi.mock('@d8d/shared-ui-components/utils/hc', () => ({
|
|
|
+ rpcClient: mockRpcClient
|
|
|
+}));
|
|
|
|
|
|
// 完整的mock响应对象
|
|
|
const createMockResponse = (status: number, data?: any) => ({
|
|
|
@@ -58,41 +78,24 @@ const createMockResponse = (status: number, data?: any) => ({
|
|
|
clone: function() { return this; }
|
|
|
});
|
|
|
|
|
|
-// Mock API client
|
|
|
+// Mock API client(保持向后兼容性,但实际使用上面的统一模拟)
|
|
|
+// 符合API模拟规范:统一模拟rpcClient函数,客户端管理器使用模拟的rpcClient
|
|
|
vi.mock('../src/api/goodsClient', () => {
|
|
|
- const mockGoodsClient = {
|
|
|
- index: {
|
|
|
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, { data: [], total: 0 }))),
|
|
|
- $post: vi.fn(() => Promise.resolve(createMockResponse(201))),
|
|
|
- },
|
|
|
- ':id': {
|
|
|
- children: {
|
|
|
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, { data: [], total: 0 }))),
|
|
|
- },
|
|
|
- setAsParent: {
|
|
|
- $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
- },
|
|
|
- parent: {
|
|
|
- $delete: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
- },
|
|
|
- $delete: vi.fn(() => Promise.resolve(createMockResponse(204))),
|
|
|
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 123, spuId: 0, tenantId: 1 }))),
|
|
|
- },
|
|
|
- batchCreateChildren: {
|
|
|
- $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
|
|
|
- },
|
|
|
- };
|
|
|
+ // 获取模拟的客户端实例(通过mockRpcClient创建)
|
|
|
+ // 符合测试策略文档的规范:直接通过模拟的rpcClient函数创建客户端
|
|
|
+ const mockClient = mockRpcClient('/');
|
|
|
|
|
|
const mockGoodsClientManager = {
|
|
|
- get: vi.fn(() => mockGoodsClient),
|
|
|
+ get: vi.fn(() => mockClient),
|
|
|
};
|
|
|
|
|
|
return {
|
|
|
goodsClientManager: mockGoodsClientManager,
|
|
|
- goodsClient: mockGoodsClient,
|
|
|
+ goodsClient: mockClient,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
+
|
|
|
import { GoodsParentChildPanel } from '../../src/components/GoodsParentChildPanel';
|
|
|
|
|
|
// Create a wrapper with QueryClient
|
|
|
@@ -119,8 +122,12 @@ describe('GoodsParentChildPanel', () => {
|
|
|
onDataChange: vi.fn(),
|
|
|
};
|
|
|
|
|
|
+ let mockGoodsClient: any;
|
|
|
+
|
|
|
beforeEach(() => {
|
|
|
vi.clearAllMocks();
|
|
|
+ // 获取模拟的客户端实例
|
|
|
+ mockGoodsClient = mockRpcClient('/');
|
|
|
});
|
|
|
|
|
|
it('应该正确渲染创建模式', () => {
|
|
|
@@ -374,12 +381,11 @@ describe('GoodsParentChildPanel', () => {
|
|
|
const mockDeleteResponse = { success: true };
|
|
|
|
|
|
// 设置mock
|
|
|
- const mockClient = require('../src/api/goodsClient').goodsClientManager.get();
|
|
|
- mockClient[':id'].$get.mockResolvedValue({
|
|
|
+ mockGoodsClient[':id'].$get.mockResolvedValue({
|
|
|
status: 200,
|
|
|
json: () => Promise.resolve(mockGoodsDetail)
|
|
|
});
|
|
|
- mockClient[':id'].$delete.mockResolvedValue({
|
|
|
+ mockGoodsClient[':id'].$delete.mockResolvedValue({
|
|
|
status: 204,
|
|
|
json: () => Promise.resolve(null) // 204 No Content 响应没有body
|
|
|
});
|
|
|
@@ -414,11 +420,11 @@ describe('GoodsParentChildPanel', () => {
|
|
|
const mockQueryClient = {
|
|
|
invalidateQueries: vi.fn()
|
|
|
};
|
|
|
- vi.spyOn(require('@tanstack/react-query'), 'useQueryClient').mockReturnValue(mockQueryClient);
|
|
|
+ const useQueryClientSpy = vi.spyOn(require('@tanstack/react-query'), 'useQueryClient');
|
|
|
+ useQueryClientSpy.mockReturnValue(mockQueryClient);
|
|
|
|
|
|
// 模拟 goodsClientManager
|
|
|
- const mockClient = require('../src/api/goodsClient').goodsClientManager.get();
|
|
|
- mockClient.batchCreateChildren.$post.mockResolvedValue({
|
|
|
+ mockGoodsClient.batchCreateChildren.$post.mockResolvedValue({
|
|
|
status: 200,
|
|
|
json: () => Promise.resolve({ success: true })
|
|
|
});
|