2017-01-10 10 views
5

जेस्ट का उपयोग करके आउटपुट यादृच्छिक फ़ंक्शन का परीक्षण कैसे करें? इस तरह:जेस्ट का उपयोग करके आउटपुट यादृच्छिक फ़ंक्शन का परीक्षण कैसे करें?

import cuid from 'cuid'; 
const functionToTest = (value) => ({ 
    [cuid()]: { 
     a: Math.random(), 
     b: new Date().toString(), 
     c: value, 
    } 
}); 

तो functionToTest('Some predictable value') के उत्पादन में किया जाएगा कुछ की तरह:

{ 
    'cixrchnp60000vhidc9qvd10p': { 
    a: 0.08715126430943698, 
    b: 'Tue Jan 10 2017 15:20:58 GMT+0200 (EET)', 
    c: 'Some predictable value' 
    }, 
} 
+1

आपको लगता है कि "परीक्षण ... कि आउटपुट यादृच्छिक है" का मतलब भी है? एक सिक्का फ्लिप करें और आप पंक्ति में दो बार सिर प्राप्त कर सकते हैं; यदि यह संभव नहीं है, तो यह यादृच्छिक नहीं है। "यादृच्छिक" का बिंदु है * आप नहीं जानते कि आप किस मूल्य की तलाश कर रहे हैं *। अभ्यास में आप एक ही इनपुट के लिए फ़ंक्शन को दो बार चला सकते हैं और अलग-अलग आउटपुट की उम्मीद कर सकते हैं, लेकिन उस समय के कुछ (बहुत कम) प्रतिशत को कार्य कोड के साथ भी असफल होना चाहिए। –

+0

निश्चित रूप से, परीक्षण यादृच्छिकता एक बकवास है। मैं पूछ रहा हूं कि सिद्धांत ** सिद्धांत ** इस तरह के मामलों का परीक्षण कैसे करें। मुझे नहीं पता कि यह कैसे करें। –

+0

कुंजी यहां परीक्षण है, यादृच्छिकता नहीं। शायद यादृच्छिक हिस्सा ओमेटेड या तो होना चाहिए। मैं परीक्षण में एक नोब हूँ, तो एक नोब सवाल है। –

उत्तर

12

यहाँ क्या मैं अपने परीक्षण फ़ाइल के शीर्ष पर डाल दिया गया है:

const mockMath = Object.create(global.Math); 
mockMath.random =() => 0.5; 
global.Math = mockMath; 

परीक्षणों में है कि फ़ाइल से चलाने के लिए, Math.random हमेशा 0.5 देता है।

पूर्ण क्रेडिट इस विचार के लिए जाना चाहिए: https://stackoverflow.com/a/40460395/2140998, जो यह स्पष्ट करता है कि यह ओवरराइट परीक्षण-विशिष्ट है। मेरा Object.create सिर्फ Math के आंतरिक के साथ छेड़छाड़ से बचने के लिए सावधानी बरतने का मेरा अतिरिक्त अतिरिक्त मामला है।

+0

मीठा! काश यह दस्तावेजों में था। – looshi

3

मैं अपने आप को निम्नलिखित प्रश्न पूछें चाहते हैं:

  • मैं वास्तव में यादृच्छिक उत्पादन का परीक्षण करने की जरूरत है ? यदि मुझे करना है, तो मुझे सबसे अधिक संभावना है कि परीक्षण श्रेणीएं हों या सुनिश्चित करें कि मुझे एक वैध प्रारूप में कोई संख्या मिली है, न कि मूल्य
  • c के मान का परीक्षण करने के लिए पर्याप्त है?

कभी-कभी किसी नकली में यादृच्छिक मूल्य की पीढ़ी को संपुटित और केवल ज्ञात मान के लिए अपने परीक्षण में पीढ़ी ओवरराइड करने के लिए एक तरीका है। यह मेरे कोड में एक आम प्रथा है। How to mock a constructor like new Date()जेस्टजे में एक समान दृष्टिकोण की तरह लगता है।

+0

ग्रेट, यही वह है जिसे मैं जानना चाहता था। न सिर्फ एक सीधा जवाब, बल्कि एक परीक्षण के उद्देश्य के पीछे कुछ। धन्यवाद! –

1

मैंने स्टुअर्ट वाट के समाधान को लिया है और इसके साथ भाग लिया है (और थोड़ी दूर ले जाया गया है)। स्टुअर्ट का समाधान अच्छा है, लेकिन मुझे यादृच्छिक संख्या जनरेटर हमेशा 0.5 थूकने के विचार से अभिभूत था - ऐसा लगता है कि ऐसी स्थितियां होंगी जहां आप कुछ भिन्नता पर गिन रहे हैं। मैं अपने पासवर्ड नमक (जेस्ट सर्वर-साइड का उपयोग करके) के लिए crypto.randomBytes का नकल करना चाहता था। मैंने इस पर थोडा समय बिताया, इसलिए मुझे लगा कि मैं ज्ञान साझा करूंगा।

मेरी बातों में से एक यह है कि यदि आपके पास संख्याओं की पुनरावर्तनीय धारा है, तो Math.random() पर एक नया कॉल पेश करने से बाद की सभी कॉलों को खराब कर दिया जा सकता है। मुझे इस समस्या के आसपास एक रास्ता मिला। यह दृष्टिकोण नकली करने के लिए आपको आवश्यक किसी भी यादृच्छिक चीज़ पर लागू होना चाहिए।

(ओर ध्यान दें: यदि आप इस चोरी करने के लिए चाहते हैं, आप Chance.js इंस्टॉल करने होंगे - yarn/npm add/install chance) में फ़ाइलों में से एक अपने package.json के {"jest":{"setupFiles"} सरणी द्वारा की दिशा में रखे इस शब्दों में कहें,

Math.random नकली करने के लिए:

const Chance = require('chance') 

const chances = {} 

const mockMath = Object.create(Math) 
mockMath.random = (seed = 42) => { 
    chances[seed] = chances[seed] || new Chance(seed) 
    const chance = chances[seed] 
    return chance.random() 
} 

global.Math = mockMath 

आप देखेंगे Math.random() अब एक पैरामीटर है कि - एक बीज। यह बीज एक स्ट्रिंग हो सकता है। इसका अर्थ यह है कि, जब आप अपना कोड लिख रहे हों, तो आप यादृच्छिक संख्या जनरेटर के लिए कॉल कर सकते हैं जिसे आप नाम से चाहते हैं। जब मैंने यह काम करने के लिए कोड में एक टेस्ट जोड़ा, तो मैंने यह बीज नहीं लगाया। यह मेरे पहले मॉक Math.random() स्नैपशॉट खराब कर दिया। लेकिन फिर जब मैंने इसे Math.random('mathTest') में बदल दिया, तो उसने "गणित" नामक एक नया जनरेटर बनाया और डिफ़ॉल्ट से अनुक्रम को रोकना बंद कर दिया।

मैंने अपने पासवर्ड लवण के लिए crypto.randomBytes भी मजाक किया। तो जब मैं अपने लवण उत्पन्न करने के लिए कोड लिखता हूं, तो मैं crypto.randomBytes(32, 'user sign up salt').toString('base64') लिख सकता हूं। इस तरह से मैं पूरी तरह से सुनिश्चित हो सकता हूं कि crypto.randomBytes पर कोई भी कॉल मेरे अनुक्रम के साथ गड़बड़ नहीं कर रहा है।

यदि कोई और इस तरह से crypto पर नकल करने में रूचि रखता है, तो यहां बताया गया है। <rootDir>/__mocks__/crypto.js अंदर इस कोड डालें:

const crypto = require.requireActual('crypto') 
const Chance = require('chance') 

const chances = {} 

const mockCrypto = Object.create(crypto) 
mockCrypto.randomBytes = (size, seed = 42, callback) => { 
    if (typeof seed === 'function') { 
    callback = seed 
    seed = 42 
    } 

    chances[seed] = chances[seed] || new Chance(seed) 
    const chance = chances[seed] 

    const randomByteArray = chance.n(chance.natural, size, { max: 255 }) 
    const buffer = Buffer.from(randomByteArray) 

    if (typeof callback === 'function') { 
    callback(null, buffer) 
    } 
    return buffer 
} 

module.exports = mockCrypto 

और फिर बस jest.mock('crypto') फोन (फिर से, मैं इसे अपने "setupFiles" में से एक में है)। चूंकि मैं इसे जारी कर रहा हूं, इसलिए मैं आगे बढ़ गया और इसे कॉलबैक विधि के साथ संगत बना दिया (हालांकि मुझे इसका उपयोग करने का कोई इरादा नहीं है)। कोड की

इन दो टुकड़े पारित these tests के सभी 17 (मैं beforeEach() रों लिए __clearChances__ कार्यों बनाया - यह सिर्फ chances हैश से सभी चाबियाँ हटा देता है)

अद्यतन: कुछ दिनों के लिए इस का उपयोग कर दिया गया और अब मुझे लगता है कि यह बहुत अच्छी तरह से काम करता है। केवल एक चीज मुझे लगता है कि शायद एक बेहतर रणनीति एक Math.useSeed समारोह है कि परीक्षण है कि Math.random

0

की आवश्यकता होती है के शीर्ष पर चलाए जाने के दौरान बनाने की जाएगी तुम हमेशा jest-mock-random

इस्तेमाल कर सकते हैं है लेकिन यह मजाक से थोड़ा और अधिक कार्यक्षमता प्रदान करता है जैसा कि पहले जवाब में प्रस्तावित किया गया है

संबंधित मुद्दे

 संबंधित मुद्दे