Jest模拟window.navigator.language为en-GB,formatCurrency仍默认en-US格式
问题根源
你的formatCurrency函数里,userLanguage是模块加载时就固定下来的——模块一被导入,就会执行const userLanguage = window.navigator.language,把当时的语言值存起来。后续测试里再模拟window.navigator.language,已经没法改变这个变量的值了,所以函数还是用的模块加载时的旧语言值,自然不会输出£符号。
解决方案
把userLanguage的获取逻辑移到formatCurrency函数内部,让每次调用函数时都实时读取最新的window.navigator.language:
修改后的formatCurrency代码:
const languageCurrency = { "en-GB": "GBP", "en-US": "USD", }; export const formatCurrency = (value) => { // 每次调用函数时才获取当前语言 const userLanguage = window.navigator.language; return Intl.NumberFormat(userLanguage, { style: "currency", currency: languageCurrency[userLanguage], }).format(value); };
测试代码调整(可选优化)
如果需要确保模拟逻辑完全生效,也可以调整测试的导入时机——先模拟window,再导入模块,避免模块加载时读取原始的window值:
describe("given formatCurrency function", () => { let windowSpy; let formatCurrency; beforeEach(() => { windowSpy = jest.spyOn(window, "window", "get"); // 先模拟环境,再重新导入模块 jest.resetModules(); formatCurrency = require("./formatCurrency").formatCurrency; }); afterEach(() => { windowSpy.mockRestore(); }); it("should format currency to £ when language is en-GB", () => { windowSpy.mockImplementation(() => ({ navigator: { language: "en-GB", }, })); expect(window.navigator.language).toBe("en-GB"); expect(formatCurrency(1000)).toBe("£1,000.00"); // 注意Intl格式化会自动添加千分位,需匹配实际输出 }); });
提示:Intl.NumberFormat在en-GB locale下格式化1000会输出带千分位的
£1,000.00,原断言的£1000.00会不匹配,需要调整断言内容。
内容的提问来源于stack exchange,提问作者Jereme
相关产品推荐
相关产品推荐

