如何在WordPress区块插件中用Jest测试wp.data及apiFetch?
Jest测试WordPress区块插件:模拟wp.data与apiFetch的方案
1. 模拟全局wp.data调用
测试环境中不存在WordPress的全局wp对象,需要手动模拟wp.data.select及getCurrentPostId方法。推荐在测试前初始化全局对象,并在每个用例中重置mock,避免用例间污染:
// 测试文件顶部初始化全局wp对象 beforeAll(() => { global.wp = { data: { select: jest.fn() } }; }); // 每个测试用例前重置mock状态 beforeEach(() => { jest.clearAllMocks(); // 让select返回包含getCurrentPostId的mock对象 const mockEditorSelect = { getCurrentPostId: jest.fn() }; wp.data.select.mockReturnValue(mockEditorSelect); });
2. 模拟apiFetch模块
apiFetch是从@wordpress/api-fetch导入的模块,直接用Jest的jest.mock模拟整个模块,返回一个可控制的mock函数:
// 测试文件顶部模拟apiFetch jest.mock('@wordpress/api-fetch', () => jest.fn());
3. 编写测试用例
针对initPageLink的不同分支编写测试,覆盖所有逻辑场景:
测试用例1:无postId时抛出错误
import { initPageLink } from './your-file-path'; import apiFetch from '@wordpress/api-fetch'; describe('initPageLink', () => { it('抛出错误当无可用postId', async () => { // 设置getCurrentPostId返回null wp.data.select().getCurrentPostId.mockReturnValue(null); await expect(initPageLink(false)).rejects.toThrow('No post ID available.'); // 验证wp.data.select的调用参数 expect(wp.data.select).toHaveBeenCalledWith('core/editor'); expect(wp.data.select().getCurrentPostId).toHaveBeenCalled(); }); });
测试用例2:useShortlink为true时返回短链接
it('返回短链接当useShortlink为true', async () => { const mockPostId = 123; const mockPost = { id: mockPostId, link: 'https://example.com/2024/05/my-post/' }; // 设置postId返回值 wp.data.select().getCurrentPostId.mockReturnValue(mockPostId); // 设置apiFetch返回模拟的post数据 apiFetch.mockResolvedValue(mockPost); const result = await initPageLink(true); // 验证短链接格式是否正确 expect(result).toBe('https://example.com/2024/05/?p=123'); // 验证apiFetch的调用路径 expect(apiFetch).toHaveBeenCalledWith({ path: `/wp/v2/posts/${mockPostId}?context=edit` }); });
测试用例3:useShortlink为false时返回原链接
it('返回原文章链接当useShortlink为false', async () => { const mockPostId = 456; const mockPost = { id: mockPostId, link: 'https://example.com/2024/05/another-post/' }; wp.data.select().getCurrentPostId.mockReturnValue(mockPostId); apiFetch.mockResolvedValue(mockPost); const result = await initPageLink(false); expect(result).toBe(mockPost.link); expect(apiFetch).toHaveBeenCalledWith({ path: `/wp/v2/posts/${mockPostId}` }); });
注意事项
- 每次测试前用
jest.clearAllMocks()重置mock调用记录,避免用例间状态污染。 - 若项目使用
@wordpress/scripts,其已集成适配WordPress的Jest配置,但手动模拟全局对象仍需自行处理。 - 可额外测试多种链接格式(如根目录文章链接
https://example.com/my-post/),确保短链接生成逻辑鲁棒性。
内容的提问来源于stack exchange,提问作者Sina
相关产品推荐
相关产品推荐

