blob: 5a68ecfc98bc6aae5bb6bf79941542ee3b05a99c [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(() => {
mockNavigate.mockClear();
// 设置模拟的 API 响应
announcementApi.getAnnouncementDetail.mockResolvedValue({
data: {
code: 200,
data: {
announcement: mockAnnouncement,
},
},
});
// 模拟钩子
useParams.mockReturnValue({ id: '1' });
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 () => {
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 () => {
announcementApi.getAnnouncementDetail.mockRejectedValue(new Error('网络错误'));
renderComponent();
await waitFor(() => {
expect(screen.getByText('获取公告详情失败')).toBeInTheDocument();
});
});
// 边界测试 - 测试公告ID不存在
it('应该处理不存在的公告ID', async () => {
announcementApi.getAnnouncementDetail.mockResolvedValue({
data: { code: 404, message: '公告不存在' },
});
renderComponent();
await waitFor(() => {
expect(screen.getByText('公告不存在')).toBeInTheDocument();
});
});
// 边界测试 - 测试其他API错误
it('应该处理服务器错误', async () => {
announcementApi.getAnnouncementDetail.mockResolvedValue({
data: { code: 500, message: '服务器错误' },
});
renderComponent();
await waitFor(() => {
expect(screen.getByText('服务器错误')).toBeInTheDocument();
});
});
});