如何Mock Number.toLocaleString()实现跨区域一致的测试结果
解决数字格式化函数跨区域测试一致性问题
方案一:修改函数,显式指定区域(推荐)
问题根源是toLocaleString()默认使用系统区域设置,导致不同地区输出格式差异。直接在函数中为toLocaleString()指定固定区域,从根源消除不一致:
export const shortNumberString = (number: number) => { if (!number) { return number === 0 ? '0' : ''; } const i = Math.floor(Math.log(number) / Math.log(1000)); // 显式指定en-US区域,确保小数点为.,千分位分隔符为, return ( Number((number / Math.pow(1000, i)).toFixed(1)).toLocaleString('en-US') + ' ' + ['', 'K', 'M', 'B'][i] ).trim(); };
修改后无论开发者所在区域是什么,函数输出都会统一为1.5 M这类格式,无需依赖测试Mock。
方案二:在Jest中正确Mock Number.prototype.toLocaleString
如果不想修改原函数,可通过以下方式在测试中全局MocktoLocaleString(),强制返回统一格式:
方式1:使用spyOn全局Mock
// 在测试文件开头添加 beforeAll(() => { jest.spyOn(Number.prototype, 'toLocaleString').mockImplementation(function() { // 模拟en-US格式,保留小数点为.,添加千分位分隔符 return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); }); }); afterAll(() => { jest.restoreAllMocks(); });
方式2:直接覆盖原型方法
如果spyOn无效,可直接替换全局Number的原型方法:
beforeAll(() => { const originalToLocaleString = Number.prototype.toLocaleString; Number.prototype.toLocaleString = function() { // 忽略传入参数,强制返回统一格式 return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); }; }); afterAll(() => { // 恢复原方法 Number.prototype.toLocaleString = originalToLocaleString; });
验证测试用例
编写测试用例确认结果一致性:
import { shortNumberString } from './your-file-path'; describe('shortNumberString', () => { test('formats 1500000 to 1.5 M', () => { expect(shortNumberString(1500000)).toBe('1.5 M'); }); test('formats 1000000 to 1 M', () => { expect(shortNumberString(1000000)).toBe('1 M'); }); test('returns 0 for 0', () => { expect(shortNumberString(0)).toBe('0'); }); });
内容的提问来源于stack exchange,提问作者Musterknabe
相关产品推荐
相关产品推荐

