如何在react-i18next中对t函数进行spy监听以测试其参数与返回值
国际化t函数调用与返回值测试方案
核心思路
要同时拿到t函数的入参和返回值,需要创建保留原翻译能力的间谍函数:既不破坏原t函数的翻译逻辑(确保返回值符合国际化配置),又能捕获每次调用的入参和返回结果用于断言。
Jest + react-i18next 实现示例
前置配置:初始化测试用i18n实例
先在测试文件中初始化i18n,加载你需要用到的国际化配置:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // 测试用国际化资源,和你实际的配置保持一致 const testTranslations = { some: { key: "Hi {{name}}" } }; i18n .use(initReactI18next) .init({ lng: 'zh-CN', resources: { 'zh-CN': { translation: testTranslations } }, fallbackLng: 'zh-CN', interpolation: { escapeValue: false } });
创建带翻译能力的间谍函数
根据你使用t函数的方式二选一即可:
// 方式1:直接监听全局导入的t函数 import * as i18nModule from 'i18next'; const tSpy = jest.spyOn(i18nModule, 't'); // 方式2:监听useTranslation hook返回的t(React项目更常用) import { useTranslation } from 'react-i18next'; jest.mock('react-i18next', () => ({ ...jest.requireActual('react-i18next'), useTranslation: jest.fn() })); // 间谍函数内部调用原t方法,保留翻译能力 const mockT = jest.fn((key, options) => i18n.t(key, options)); useTranslation.mockReturnValue({ t: mockT, i18n });
执行断言
在组件渲染/业务逻辑执行完成后,调用断言即可:
// 注意原示例中的 toHaveBeenCaledWith 存在拼写错误,正确写法如下 expect(mockT).toHaveBeenCalledWith("some.key", { name: "Ash" }); expect(mockT).toHaveReturnedWith("Hi Ash");
Vitest 适配方案
逻辑和Jest完全一致,仅需替换对应的API前缀即可:
// 替换jest为vi import * as i18nModule from 'i18next'; const tSpy = vi.spyOn(i18nModule, 't'); // mock hook的写法同理 vi.mock('react-i18next', () => ({ ...vi.importActual('react-i18next'), useTranslation: vi.fn() })); const mockT = vi.fn((key, options) => i18n.t(key, options)); useTranslation.mockReturnValue({ t: mockT, i18n });
注意事项
- 不要直接把t函数mock为空函数,必须保留原翻译逻辑,否则无法拿到正确的返回值做
toHaveReturnedWith断言 - 多语言场景可以在测试用例前修改
i18n.lng的值,即可测试不同语言下的返回值是否符合预期 - 异步组件/逻辑需要等待执行完成后再做断言,避免捕获不到调用记录
内容的提问来源于stack exchange,提问作者narukaioh
相关产品推荐
相关产品推荐

