कैसे n.js में process.env को स्टब करने के लिए?


81

मैं के process.env.FOOसाथ ठोकर खाना चाहता हूँ bar

var sinon = require('sinon');
var stub = sinon.stub(process.env, 'FOO', 'bar');

मैं उलझन में हूं। मैंने दस्तावेज़ पढ़ा, लेकिन फिर भी मुझे अभी तक समझ नहीं आया है। sinonjs डॉक्स

sinonjs एक उदाहरण है, sinonjs ठीक नहीं है।


क्या आप बता सकते हैं कि आप पर्यावरण की विविधता को क्यों रोकेंगे? क्या आप यह यूनिक्स जैसे ओएस या विंडोज पर कर रहे हैं?
स्लीवेटमैन

1
@slebetman कॉन्फ़िगरेशन के लिए पर्यावरण चर पर भरोसा करना आम है, जिस सेवा पर आप भरोसा करते हैं उसके लिए एपीआई कुंजी की तरह। 12factor.net देखें ।
एंड्रयू होमियर

1
@AndrewHomeyer: हाँ, लेकिन आप उन्हें ठूंठ नहीं देते हैं - आप उन्हें परीक्षण के लिए सही ढंग से सेट करते हैं
बेधड़क जूल

जवाबों:


74

मेरी समझ से process.env, आप बस इसके गुणों को सेट करते समय किसी अन्य चर की तरह इसका इलाज कर सकते हैं। हालांकि, ध्यान रखें कि प्रत्येक मूल्य process.envएक स्ट्रिंग होना चाहिए। इसलिए, यदि आपको अपने परीक्षण में एक विशेष मूल्य की आवश्यकता है:

   it('does something interesting', () => {
      process.env.NODE_ENV = 'test';
      // ...
   });

अन्य परीक्षणों में लीक होने की स्थिति से बचने के लिए, चर को उसके मूल मूल्य पर रीसेट करना या उसे पूरी तरह से हटाना सुनिश्चित करें:

   afterEach(() => {
       delete process.env.NODE_ENV;
   });

8
इससे मेरा काम बनता है। एक बात का ध्यान रखें कि यदि आप एक मॉड्यूल का परीक्षण कर रहे हैं जो मॉड्यूल को लोड करते समय NODE_ENV को पढ़ता है, तो आप संभवतः मॉड्यूल लोड करने से पहले NODE_ENV सेट करना चाहेंगे (अर्थात NODE_ENV को पहले से ब्लॉक में सेट किया जा सकता है।) यह स्पष्ट लग सकता है। , लेकिन इसने मुझे पहले फंसा दिया है।
आतंक

यदि आपको समस्याएँ हैं, तो क्या आप किसी को देखने के लिए एक कोड स्निपेट पोस्ट कर सकते हैं? मैंने अपना जवाब मोचा टेस्ट रनर के सिंटैक्स को ध्यान में रखते हुए लिखा था, लेकिन इसे किसी अन्य रनर के साथ भी काम करना चाहिए (जैसे लैब)।
जोशुआ डटन

2
यह काम करता है, लेकिन मुझे इस्तेमाल करते समय एक विचित्रता मिली jest। अपने प्रोडक्शन कोड में मैंने env से एक कास्ट (उदा const X = process.env.X) को सौंपा । कांस्ट को (ES) मॉड्यूल स्कोप में घोषित किया गया था, फंक्शन स्कोप को नहीं। मेरे टेस्ट हमेशा jest --watchरिटायर्ड टेस्ट रन पर पास हुए , लेकिन पहले रन पर हमेशा असफल रहे। एक आदेश देने वाला मुद्दा है जो मुझे पूरी तरह से समझ नहीं आया है। बस सुनिश्चित करें कि आप हमेशा process.envअपने उत्पादन कोड (यानी एक फ़ंक्शन में) से सीधे पढ़ रहे हैं , और मॉड्यूल स्तर पर इसे कैशिंग नहीं कर रहे हैं।
जेसी बुकानन

1
यदि आप किसी फ़ंक्शन में process.env का मूल्यांकन कर रहे हैं, तो यह अच्छी तरह से काम करता है, लेकिन यदि यह स्थिर है। उदाहरण के लिए, const myValue = process.env.value ? process.env.value : 'default'यदि आप एक परीक्षा के अंदर process.env.value सेट करते हैं तो मैं काम नहीं कर सकता था । हालाँकि, const myValue = () => (process.env.value ? process.env.value : 'default') उम्मीद के मुताबिक काम करता है!
राफेल मार्क्‍स

इसी नस में, मेरे पास: const SWITCH_ON = (process.env.SWITCH_ON.toLowerCase() === 'true');जो काम नहीं करता था, इसलिए मैंने इसे दो लाइनों में बदल दिया: var switchOn = process.env.SWITCH_ON; const SWITCH_ON = (switchOn === undefined ? false : switchOn.toLowerCase() === 'true');प्रारंभिक ने मुझे undefinedत्रुटियां .toLowerCase()
स्काला सरगर्म

25

मैं process.envअपने यूनिट परीक्षणों में इसे ठीक से क्लोन करके और इसे पुनर्स्थापित करने वाले एक फाड़नेवाला विधि में ठीक से जमा होने में सक्षम था ।

मोचा का उपयोग कर उदाहरण

const env = Object.assign({}, process.env);

after(() => {
    process.env = env;
});

...

it('my test', ()=> {
    process.env.NODE_ENV = 'blah'
})

ध्यान रखें यह केवल तभी काम करेगा जब process.env केवल उस फ़ंक्शन में पढ़ा जा रहा है जिसे आप परीक्षण कर रहे हैं। उदाहरण के लिए यदि आप जिस कोड का परीक्षण कर रहे हैं वह चर को पढ़ता है और इसे एक क्लोजर में उपयोग करता है तो यह काम नहीं करेगा। आप शायद कैश्ड को अवैध रूप से परीक्षण करने की आवश्यकता को अमान्य करते हैं।

उदाहरण के लिए निम्नलिखित में एनवी स्टब नहीं होगा:

const nodeEnv = process.env.NODE_ENV;

const fnToTest = () => {
   nodeEnv ...
}

3
यह प्रक्रिया ज्यादातर काम की थी। मुझे "आफ्टर" मेथड को ट्विक करना था। after(() => { process.env = Object.assign({}, env); }); अन्यथा परीक्षण साझा प्रतिलिपि में हेरफेर करेंगे। प्रत्येक परीक्षण के बाद एक नए संस्करण को सेट करने की आवश्यकता है।
काइल

1
@ केली .. नहीं यह नहीं होगा? अपनी फ़ाइल के शीर्ष पर एक बार सेटअप करने के बाद, यह आपके टेस्ट सूट की शुरुआत में इसे फिर से स्थापित किया जाएगा।
प्रिज़नर

4

एक spec-helper.coffeeया कुछ इसी तरह से जहां आप अपने पापोन सैंडबॉक्स को सेट करते हैं, मूल का ट्रैक रखें process.envऔर प्रत्येक परीक्षण के बाद इसे पुनर्स्थापित करें, इसलिए आप परीक्षणों के बीच लीक नहीं करते हैं और हर बार रीसेट करने के लिए याद नहीं रखना पड़ता है।

_ = require 'lodash'
sinon = require 'sinon'

beforeEach ->
    @originalProcessEnv = _.cloneDeep process.env

afterEach ->
    process.env = _.cloneDeep @originalProcessEnv

अपने परीक्षण में, process.envसामान्य रूप से उपयोग करें ।

it 'does something based on an env var', ->
    process.env.FOO = 'bar'

underscoreके cloneसमारोह के स्थान पर काम करता है cloneDeepअगर आप पहले से ही उपयोग कर रहे हैं उपयोगी - underscoreके बजाय lodash
रोब

4

सिनॉन के साथ आप इस तरह किसी भी चर को स्टब कर सकते हैं।

 const myObj = {
    example: 'oldValue', 
 };

 sinon.stub(myObj, 'example').value('newValue');

 myObj.example; // 'newValue'

यह उदाहरण फॉर्म सिनोन डॉक्यूमेंटेशन है। https://sinonjs.org/releases/v6.1.5/stubs/


उस ज्ञान के साथ, आप किसी भी पर्यावरण चर को रोक सकते हैं। आपके मामले में यह इस तरह दिखेगा:

 let stub = sinon.stub(process.env, 'FOO').value('bar');

5
मुझे एक त्रुटि मिली "गैर-विद्यमान स्वयं की संपत्ति FOO को स्टब नहीं कर सकता"। इसके अलावा मेरे परीक्षण चलाने के लिए हालांकि wallaby.js का उपयोग करना।
विल लवेट

1
प्रश्न के उत्तर को पोस्ट करने के लिए धन्यवाद "एन्वा वर जैसा दिखने वाला स्टबिंग कैसा लगता है?" बजाय सिर्फ कह हम क्योंकि हम उन्हें मैन्युअल रूप से फेरबदल कर सकते हैं की जरूरत नहीं है की :)
विल

मुझे @WillLovett के समान त्रुटि मिली और अपनी यूनिट-परीक्षण स्क्रिप्ट के शीर्ष के पास आवश्यकता कॉल जोड़कर इसे हल किया: require('dotenv').config();मुझे एहसास हुआ कि यह सामान्य रूप से तब प्राप्त होता है जब मेरा आवेदन चलता है, लेकिन अगर मैं अपनी यूनिट-परीक्षण सीधे चला रहा हूं, तो यह आवश्यकता कथन अनुपस्थित होगा।
वॉन पिटमैन

4

यूनिट परीक्षण के दौरान प्रक्रिया को जल्दी से कैसे मॉक करें।

https://glebbahmutov.com/blog/mocking-process-env/

const sinon = require('sinon')
let sandbox = sinon.createSandbox()

beforeEach(() => {
  sandbox.stub(process.env, 'USER').value('test-user')
})

it('has expected user', () => {
  assert(process.env.USER === 'test-user', 'wrong user')
})

afterEach(() => {
  sandbox.restore()
})

लेकिन उन गुणों के बारे में जो परीक्षण से पहले प्रक्रिया में मौजूद नहीं हो सकते हैं। आप निम्नलिखित पैकेज का उपयोग कर सकते हैं और तब आप एन वी चर का अस्तित्व नहीं बना पाएंगे।

https://github.com/bahmutov/mocked-env


यह तब काम नहीं करेगा जब process.env.USERपहले से ही मूल्य नहीं है।
सोहेल सी

0

आप इसका उपयोग कर सकते हैं यदि आप एक कुंजी को स्टुब करना चाहते हैं जो प्रक्रिया में मौजूद नहीं है

const sinon = require('sinon')
let sandbox = sinon.createSandbox();
sandbox.stub(process, 'env').value({ 'SOME_KEY': 'SOME_VALUE' });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.