feat: 提升测试覆盖率并优化测试用例
新增测试: - use-page-views.test.ts: 测试页面浏览跟踪功能 - api-response.test.ts: 测试API响应辅助函数 - analytics.test.ts: 优化分析函数测试 覆盖率提升: - branches: 40% -> 41.62% - functions: 45% -> 47.3% - lines: 50% -> 52.82% - statements: 50% -> 51.82% 更新覆盖率阈值到当前水平
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { usePageViews, PageViewsTracker } from './use-page-views';
|
||||
import * as analytics from '@/lib/analytics';
|
||||
|
||||
jest.mock('next/navigation', () => ({
|
||||
usePathname: jest.fn(),
|
||||
useSearchParams: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/lib/analytics', () => ({
|
||||
pageview: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('usePageViews', () => {
|
||||
const mockPageview = analytics.pageview as jest.Mock;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const mockUsePathname = require('next/navigation').usePathname as jest.Mock;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const mockUseSearchParams = require('next/navigation').useSearchParams as jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockUsePathname.mockReturnValue('/test-path');
|
||||
mockUseSearchParams.mockReturnValue({
|
||||
toString: () => 'param=value',
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('应该在pathname变化时调用pageview', () => {
|
||||
renderHook(() => usePageViews());
|
||||
|
||||
expect(mockPageview).toHaveBeenCalledWith('/test-path?param=value');
|
||||
});
|
||||
|
||||
it('应该在没有searchParams时只使用pathname', () => {
|
||||
mockUseSearchParams.mockReturnValue({
|
||||
toString: () => '',
|
||||
});
|
||||
|
||||
renderHook(() => usePageViews());
|
||||
|
||||
expect(mockPageview).toHaveBeenCalledWith('/test-path');
|
||||
});
|
||||
|
||||
it('应该在pathname为空时不调用pageview', () => {
|
||||
mockUsePathname.mockReturnValue(null);
|
||||
|
||||
renderHook(() => usePageViews());
|
||||
|
||||
expect(mockPageview).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('PageViewsTracker应该渲染null', () => {
|
||||
const { result } = renderHook(() => PageViewsTracker());
|
||||
|
||||
expect(result.current).toBeNull();
|
||||
});
|
||||
});
|
||||
+33
-57
@@ -1,95 +1,71 @@
|
||||
jest.mock('./analytics', () => {
|
||||
const actual = jest.requireActual('./analytics');
|
||||
return {
|
||||
...actual,
|
||||
pageview: jest.fn(),
|
||||
event: jest.fn(),
|
||||
trackContactForm: jest.fn(),
|
||||
trackButtonClick: jest.fn(),
|
||||
trackPageView: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
import {
|
||||
pageview,
|
||||
event,
|
||||
trackContactForm,
|
||||
trackButtonClick,
|
||||
trackPageView,
|
||||
GA_MEASUREMENT_ID,
|
||||
} from './analytics';
|
||||
|
||||
describe('analytics', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
describe('exports', () => {
|
||||
it('应该导出所有必要的函数', () => {
|
||||
expect(pageview).toBeDefined();
|
||||
expect(event).toBeDefined();
|
||||
expect(trackContactForm).toBeDefined();
|
||||
expect(trackButtonClick).toBeDefined();
|
||||
expect(trackPageView).toBeDefined();
|
||||
expect(GA_MEASUREMENT_ID).toBeDefined();
|
||||
});
|
||||
|
||||
it('所有函数应该是可调用的', () => {
|
||||
expect(() => pageview('/test')).not.toThrow();
|
||||
expect(() => event('click', 'button')).not.toThrow();
|
||||
expect(() => trackContactForm({ name: 'test' })).not.toThrow();
|
||||
expect(() => trackButtonClick('submit', 'header')).not.toThrow();
|
||||
expect(() => trackPageView('Home', '/home')).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('pageview', () => {
|
||||
it('should be defined', () => {
|
||||
expect(pageview).toBeDefined();
|
||||
expect(typeof pageview).toBe('function');
|
||||
});
|
||||
|
||||
it('should be callable', () => {
|
||||
pageview('/test-page');
|
||||
expect(pageview).toHaveBeenCalledWith('/test-page');
|
||||
it('应该接受URL参数', () => {
|
||||
expect(() => pageview('/test-page')).not.toThrow();
|
||||
expect(() => pageview('/another-page?param=value')).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('event', () => {
|
||||
it('should be defined', () => {
|
||||
expect(event).toBeDefined();
|
||||
expect(typeof event).toBe('function');
|
||||
it('应该接受必需参数', () => {
|
||||
expect(() => event('click', 'button')).not.toThrow();
|
||||
});
|
||||
|
||||
it('should be callable with all parameters', () => {
|
||||
event('click', 'button', 'submit', 1);
|
||||
expect(event).toHaveBeenCalledWith('click', 'button', 'submit', 1);
|
||||
});
|
||||
|
||||
it('should be callable with minimal parameters', () => {
|
||||
event('click', 'button');
|
||||
expect(event).toHaveBeenCalledWith('click', 'button');
|
||||
it('应该接受可选参数', () => {
|
||||
expect(() => event('click', 'button', 'label', 1)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackContactForm', () => {
|
||||
it('should be defined', () => {
|
||||
expect(trackContactForm).toBeDefined();
|
||||
expect(typeof trackContactForm).toBe('function');
|
||||
});
|
||||
|
||||
it('should be callable', () => {
|
||||
it('应该接受表单数据', () => {
|
||||
const formData = {
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
message: 'Test message',
|
||||
};
|
||||
trackContactForm(formData);
|
||||
expect(trackContactForm).toHaveBeenCalledWith(formData);
|
||||
expect(() => trackContactForm(formData)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackButtonClick', () => {
|
||||
it('should be defined', () => {
|
||||
expect(trackButtonClick).toBeDefined();
|
||||
expect(typeof trackButtonClick).toBe('function');
|
||||
});
|
||||
|
||||
it('should be callable', () => {
|
||||
trackButtonClick('submit', 'header');
|
||||
expect(trackButtonClick).toHaveBeenCalledWith('submit', 'header');
|
||||
it('应该接受按钮名称和位置', () => {
|
||||
expect(() => trackButtonClick('submit', 'header')).not.toThrow();
|
||||
expect(() => trackButtonClick('cancel', 'footer')).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackPageView', () => {
|
||||
it('should be defined', () => {
|
||||
expect(trackPageView).toBeDefined();
|
||||
expect(typeof trackPageView).toBe('function');
|
||||
});
|
||||
|
||||
it('should be callable', () => {
|
||||
trackPageView('Home Page', '/home');
|
||||
expect(trackPageView).toHaveBeenCalledWith('Home Page', '/home');
|
||||
it('应该接受页面标题和路径', () => {
|
||||
expect(() => trackPageView('Home Page', '/home')).not.toThrow();
|
||||
expect(() => trackPageView('About Page', '/about')).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user