我使用Enzyme和enzyme-to-json对我的React组件进行Jest快照测试。我正在测试DateRange
组件的浅快照,这些组件呈现具有当前范围的显示字段(例如5/20/2016 - 7/18/2016
)和两个允许选择DateInput
的{{1}}组件值。这意味着我的快照包含Date
我在Date
道具中传递给组件的DateInput
以及它自己解析的文本表示。在我的测试中,我使用new Date(1995, 4, 23)
创建了一些固定日期。
当我在不同时区运行测试时,会生成不同的快照,因为Date(year, month, ...)
构造函数会在本地时区创建日期。例如。使用new Date()
会在本地时区和CI服务器上的运行之间产生快照差异。
- value={1995-05-22T22:00:00.000Z}
+ value={1995-05-23T00:00:00.000Z}
我尝试从日期中删除时区偏移量,但随后快照在显示字段值中有所不同,其中使用了与本地时区相关的表示。
- value={5/20/2016 - 7/18/2016}
+ value={5/19/2016 - 7/17/2016}
如何让我的测试在快照中生成相同的Date
,无论他们在哪个时区运行?
答案 0 :(得分:46)
我挣扎了好几个小时/天,只有这对我有用:
1)在你的测试中:
Date.now = jest.fn(() => new Date(Date.UTC(2017, 7, 9, 8)).valueOf())
2)然后在运行测试之前更改TZ
env var。
所以我的package.json中的脚本:
( Mac&仅限Linux )
"test": "TZ=America/New_York react-scripts test --env=jsdom",
( Windows )
"test": "set TZ=America/New_York && react-scripts test --env=jsdom",
答案 1 :(得分:4)
我最终得到了一个由两部分组成的解决方案。
永远不要以与时区相关的方式在测试中创建Date
个对象。如果您不想直接使用时间戳来获得可读的测试代码,请使用Date.UTC
,例如
new Date(Date.UTC(1995, 4, 23))
Date
转换为显示值的日期格式化程序,以便返回与时区无关的表示形式,例如:使用Date::toISOString()
。 幸运的是,在我的情况下,这很容易,因为我只需要在我的本地化模块中模拟formatDate
函数。如果组件以某种方式将Date
转换为字符串,可能会更难。 在我到达上述解决方案之前,我试图以某种方式更改快照的创建方式。这很丑陋,因为酶到json保存了toISOString()
的本地副本,所以我不得不使用_.cloneDeepWith
并修改所有Date
。无论如何它对我来说都没有用,因为我的测试还包含Date
从时间戳创建的情况(组件比我上面描述的要复杂得多)以及那些和我之间的日期之间的相互作用明确地在测试中创建。所以我首先必须确保我的所有日期定义都指的是相同的时区,其余时间也是如此。
更新(2017年11月3日):当我最近检查enzyme-to-json
时,我无法找到toISOString()
的本地保存,所以可能是&#39 ; s不再是问题而且可以被嘲笑。尽管如此,我还是无法在历史中找到它,所以也许我只是错误地注意到哪个库做了它。自担风险:)
答案 2 :(得分:2)
我通过使用timezone-mock
来做到这一点,它在内部替换了全局Date
对象,这是我能找到的最简单的解决方案。
该程序包支持一些测试时区。
import timezoneMock from 'timezone-mock';
describe('when in PT timezone', () => {
beforeAll(() => {
timezoneMock.register('US/Pacific');
});
afterAll(() => {
timezoneMock.unregister();
});
// ...
答案 3 :(得分:0)
我最终通过模拟toLocaleString
(或者你使用的任何toString方法)原型来解决这个问题。使用sinon
我做了:
var toLocaleString;
beforeAll(() => {
toLocaleString = sinon.stub(Date.prototype, 'toLocaleString', () => 'fake time')
})
afterAll(() => {
toLocaleString.restore()
})
这样,如果你直接从Date
对象生成字符串,那么你仍然可以。
答案 4 :(得分:0)
答案 5 :(得分:0)
将TZ=UTC
添加到我的.env
文件中为我解决了这个问题。