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