如何在Jest中模拟Number.toLocaleString使用的浏览器区域设置?
如何在Jest中模拟Number.toLocaleString的浏览器区域设置
你遇到的问题本质是:Jest运行在Node.js环境中,Number.toLocaleString()无参数时的默认区域并不读取window.navigator.language,而是使用Node.js的系统默认区域或Intl API的默认配置,所以mock navigator无效。下面是几种可行的解决方法:
方法1:直接Mock Number.prototype.toLocaleString
针对无参数调用的场景,直接重写原型方法,指定目标区域:
it('should format correctly (fr-CA)', () => { const originalToLocaleString = Number.prototype.toLocaleString; // 监听toLocaleString方法 const mock = jest.spyOn(Number.prototype, 'toLocaleString').mockImplementation(function() { // 无参数时强制使用fr-CA区域 if (arguments.length === 0) { return originalToLocaleString.call(this, 'fr-CA'); } // 有参数时保留原逻辑 return originalToLocaleString.apply(this, arguments); }); const result = 12345678.9.toLocaleString(); expect(result).toEqual('12 345 678,9'); // 恢复原方法,避免影响其他测试 mock.mockRestore(); });
方法2:Mock Intl.NumberFormat(底层依赖)
Number.toLocaleString()底层基于Intl.NumberFormat实现,所以可以直接mock这个构造函数,默认使用目标区域:
beforeEach(() => { jest.mock('intl', () => { const originalIntl = jest.requireActual('intl'); return { ...originalIntl, // 当未传入locale时,默认使用fr-CA NumberFormat: jest.fn((locale = 'fr-CA', options) => { return new originalIntl.NumberFormat(locale, options); }), }; }); }); afterEach(() => { jest.unmock('intl'); }); it('should format correctly (fr-CA)', () => { const result = 12345678.9.toLocaleString(); expect(result).toEqual('12 345 678,9'); });
方法3:全局设置Node.js环境区域(慎用)
通过设置环境变量强制Node.js使用目标区域,这种方法会全局生效,适合所有测试都需要统一区域的场景:
// 在Jest的setup文件或测试文件顶部添加 process.env.LC_ALL = 'fr-CA'; process.env.LANG = 'fr-CA';
注意:修改环境变量后需要重启Jest才会生效,不适合单测中切换不同区域的场景。
内容的提问来源于stack exchange,提问作者Alex von Brandenfels
相关产品推荐
相关产品推荐

