如何在JavaScript里面mock时区?

在做JavaScript测试的时候,如果我们的代码里有用到日期,那么可能在某些情况下会导致测试不能稳定跑。比如:对包含日期显示的UI做了Snapshot测试,但是测试代码可能会在本地、远程服务器等环境跑,时区却不一样。

这种情况下,我们就希望执行测试的时候,代码获取的是一个固定的时区,而不是运行电脑设置的时区。我找了一些资料,发现有一些办法:

1. 使用环境变量来设置Node.js代码的时区。

可以使用process.env.TZ来设置时区。

process.env.TZ = 'UTC';

这种方式最简单,但是有个缺点:在Windows系统里,这种方式无效!

2. 使用封装好的第三方库set-tz

set-tz这个库仍然是使用process.env.TZ的方式,这种方式消除了不同系统间的差异,因此可以设置代码执行的时区。

const setTZ = require('set-tz')
setTZ('UTC')

这种方式也有个缺点,就是为了让Windows时区设置有效,通过系统调用改变了系统的时区设置。测试开始时修改系统时区,测试结束时再恢复系统原来的时区。因此,如果测试运行中被手动停掉,那么系统时区就不会自动恢复了,这就给使用电脑的人带来一些麻烦,因为不是那么好!

3. 使用timezone-mock库。

timezone-mock库不是使用process.env.TZ的方式,而是用MockDate替换了JavaScript运行时的Date对象,MockDate实现了原生Date对象的方法。因此,这种方式避免了操作系统间的区别,也不会去修改系统的时区,这种方式比较理想。

但是实际用的时候,还是有些不理想的地方,那就是MockDate的功能实现不完善。有些方法目前没有实现:

  1. toLocaleDateString()
  2. toLocaleTimeString()
  3. toTimeString()

如果代码里面没使用上述的方法,那么这个库还是可以用的。