blob: 7f44ecd4b4bb0e249a11b47e34305233b1e0320c [file] [log] [blame]
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter, Route, Routes, useNavigate, useParams, useLocation } from 'react-router-dom';
import AnnouncementDetail from './AnnouncementDetail';
import * as announcementApi from '../api/announcement';
// Mock API 模块
jest.mock('../api/announcement');
// Mock 路由钩子
const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
useParams: jest.fn(),
useLocation: jest.fn(),
}));
describe('AnnouncementDetail 组件', () => {
const mockAnnouncement = {
id: 1,
title: '测试公告标题',
content: '这是测试公告内容\n这是第二行内容',
createTime: '2023-01-01T00:00:00Z',
};
beforeEach(() => {
// 重置 mock 函数
mockNavigate.mockClear();
// 设置模拟的 API 响应
announcementApi.getAnnouncementDetail.mockResolvedValue({
data: {
code: 200,
data: {
announcement: mockAnnouncement
}
}
});
// 模拟 useParams
useParams.mockReturnValue({ id: '1' });
// 模拟 useLocation
useLocation.mockReturnValue({
state: { fromTab: 'announcement' }
});
});
const renderComponent = () => {
return render(
<MemoryRouter initialEntries={['/announcement/1']}>
<Routes>
<Route path="/announcement/:id" element={<AnnouncementDetail />} />
{/* 添加一个模拟的公告列表路由用于导航测试 */}
<Route path="/dashboard/announcement" element={<div>公告列表</div>} />
</Routes>
</MemoryRouter>
);
};
it('应该正确加载和显示公告详情', async () => {
renderComponent();
// 等待数据加载完成
await waitFor(() => {
expect(screen.getByText('测试公告标题')).toBeInTheDocument();
expect(screen.getByText('这是测试公告内容')).toBeInTheDocument();
expect(screen.getByText('这是第二行内容')).toBeInTheDocument();
});
});
it('应该处理公告加载失败的情况', async () => {
// 模拟 API 返回错误
announcementApi.getAnnouncementDetail.mockResolvedValue({
data: {
code: 404,
message: '公告不存在'
}
});
renderComponent();
await waitFor(() => {
expect(screen.getByText('公告不存在')).toBeInTheDocument();
});
});
it('应该能够返回公告区', async () => {
renderComponent();
await waitFor(() => {
expect(screen.getByText('测试公告标题')).toBeInTheDocument();
});
fireEvent.click(screen.getByRole('button', { name: /返回/i }));
// 检查是否导航回公告区
expect(mockNavigate).toHaveBeenCalledWith('/dashboard/announcement');
});
it('应该显示加载错误时的UI', async () => {
// 模拟 API 抛出错误
announcementApi.getAnnouncementDetail.mockRejectedValue(new Error('网络错误'));
renderComponent();
await waitFor(() => {
expect(screen.getByText('获取公告详情失败')).toBeInTheDocument();
});
});
});