javascript तिथि ऑब्जेक्ट का उपयोग करने वाले घटक विभिन्न समयक्षेत्रों में विभिन्न स्नैपशॉट्स का उत्पादन करते हैं




reactjs jestjs (3)

मैं अपने रिएक्ट घटकों के जेस्ट स्नैपशॉट परीक्षण करने के लिए एंजाइम-टू-जेसन के साथ एंजाइम का उपयोग कर रहा हूं। मैं एक DateRange घटक के उथले स्नैपशॉट का परीक्षण कर रहा हूं जो वर्तमान श्रेणी (जैसे 5/20/2016 - 7/18/2016 DateInput ) के साथ एक प्रदर्शन फ़ील्ड को DateInput करता है और दो DateInput घटकों, जो कि Date मान को चुनने की अनुमति देता है। इसका मतलब यह है कि मेरे स्नैपशॉट में Date I DateInput और टेक्स्ट प्रस्तुतीकरण में दोनों घटक के पास होने वाला Date होता है जो स्वयं को हल करता है मेरे परीक्षण में मैं new Date(1995, 4, 23) का उपयोग करके कुछ निश्चित तिथियां बना रहा हूं

जब मैं विभिन्न समयक्षेत्रों में अपना परीक्षण चलाता हूं, तो यह अलग स्नैपशॉट बनाती है , क्योंकि Date(year, month, ...) निर्माता स्थानीय समयक्षेत्र में दिनांक बनाता है उदाहरण के लिए new Date() का उपयोग मेरे स्थानीय समयक्षेत्र में और हमारे सीआई सर्वर पर रनों के बीच स्नैपशॉट में यह अंतर पैदा करता है।

- 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 कैसे बना सकता हूं, इसके बावजूद वे उस समय के क्षेत्र में चाहे जो चल रहे हों?


मैं इस के आसपास toLocaleString (या जो कुछ भी करने के लिए toLocaleString विधि का उपयोग कर रहे हैं) प्रोटोटाइप का मज़ाक उड़ा द्वारा समाप्त हो रहा है मैंने किया sinon का प्रयोग किया:

var toLocaleString;

beforeAll(() => {
    toLocaleString = sinon.stub(Date.prototype, 'toLocaleString', () => 'fake time')
})

afterAll(() => {
    toLocaleString.restore()
})

इस तरह यदि आप स्ट्रिंग सीधे किसी Date ऑब्जेक्ट से बना रहे हैं, तो आप अभी भी ठीक हैं।


मैं दो हिस्सों के शामिल समाधान के साथ समाप्त हुआ

  1. समयक्षेत्र-निर्भर तरीके से परीक्षणों में Date ऑब्जेक्ट कभी भी नहीं बनाएं यदि आप टाइमस्टैंप का उपयोग सीधे पढ़ने योग्य टेस्ट कोड के लिए नहीं करना चाहते हैं, तो Date.UTC , उदाहरण के लिए उपयोग करें

    new Date(Date.UTC(1995, 4, 23))
  2. तारीख Date::toISOString() को प्रदर्शित मानों को चालू करने के लिए उपयोग किए जाने वाले Date::toISOString() करें, ताकि वह समय-क्षेत्र-स्वतंत्र प्रतिनिधित्व वापस कर सके, जैसे Date::toISOString() उपयोग करें। सौभाग्य से, यह मेरे मामले में आसान था, क्योंकि मुझे अपने स्थानीयकरण मॉड्यूल में formatDate फ़ंक्शन का formatDate करने की आवश्यकता थी यह शायद कठिन हो सकता है कि घटक किसी तरह तार पर अपनी तरफ से मुड़ते हैं।

इससे पहले कि मैं ऊपर दिए गए समाधान पर पहुंचे, मैंने किसी तरह बदल दिया कि स्नैपशॉट्स को कैसे बनाया जाए। यह बदसूरत था, क्योंकि एंजाइम-टू- toISOString() एक स्थानीय प्रतिलिपि को toISOString() को बचाता है, इसलिए मुझे _.cloneDeepWith का उपयोग _.cloneDeepWith और सभी Date संशोधित करना था। यह मेरे लिए वैसे भी काम नहीं कर रहा था, क्योंकि मेरे परीक्षणों में टाइमस्टैम्प से Date रचना का घटक भी था (यह घटक मेरे ऊपर वर्णित से थोड़ा अधिक जटिल है) और उन दोनों के बीच परस्परक्रिया और मैं परीक्षणों में स्पष्ट रूप से बना रहा था। इसलिए मुझे पहली बार यह सुनिश्चित करना पड़ा कि मेरी सभी दिनांक परिभाषाएं उसी समयक्षेत्र की बात कर रही थीं और बाकी का अनुसरण किया गया था।

अपडेट (11/3/2017): जब मैंने हाल ही में enzyme-to-json जेसन की जांच की तो मैं toISOString() स्थानीय toISOString() को स्थानीय बचत करने में सक्षम नहीं था, इसलिए हो सकता है कि अब कोई मुद्दा नहीं है और यह मजाक किया जा सकता है। मैं इसे इतिहास में या तो नहीं देख पा रहा हूं, इसलिए शायद मैंने गलत तरीके से नोट किया कि यह पुस्तकालय क्या किया। अपने खुद के जोखिम पर टेस्ट करें :)


मैं घंटों / दिन के लिए इस के साथ संघर्ष किया और केवल यह मेरे लिए काम किया:

1) आपके परीक्षण में:

Date.now = jest.fn(() => new Date(Date.UTC(2017, 7, 9, 8)).valueOf())

2) फिर अपने परीक्षणों को चलाने से पहले TZ एनवाई वर् बदल दें। तो मेरे पैकेज में लिपि। जेएसन:

"test": "TZ=America/New_York react-scripts test --env=jsdom",