Ich habe Stuart Watts Lösung genommen und bin damit gelaufen (und ein bisschen davon weggerissen). Stuart's Lösung ist gut, aber ich war nicht begeistert von der Idee, dass ein Zufallszahlengenerator immer 0.5 ausspuckt - es scheint, als gäbe es Situationen, in denen man auf eine gewisse Abweichung setzt. Ich wollte auch crypto.randomBytes
für meine Passwort-Salze (mit Jest Server-Seite) spotten. Ich verbrachte ein bisschen Zeit damit, also dachte ich, ich würde das Wissen teilen.
Eines der Dinge, die mir aufgefallen sind, ist, dass, selbst wenn Sie einen wiederholbaren Strom von Zahlen haben, die Einführung eines neuen Anrufs zu Math.random()
alle nachfolgenden Aufrufe vermasseln könnte. Ich habe einen Weg gefunden, dieses Problem zu umgehen. Dieser Ansatz sollte auf ziemlich jede beliebige Sache angewendet werden können, die Sie verspotten müssen.
(Randbemerkung: Wenn Sie diese stehlen wollen, werden Sie Chance.js installieren müssen - yarn/npm add/install chance
)
Math.random
zu verspotten, dieses in eine der Dateien an, indem Sie Ihre package.json
wies ‚s {"jest":{"setupFiles"}
Array:
Sie werden feststellen, dass Math.random()
jetzt einen Parameter hat - ein Seed. Dieser Seed kann eine Zeichenfolge sein. Das bedeutet, dass Sie während des Schreibens Ihres Codes den gewünschten Zufallszahlengenerator nach Namen aufrufen können. Als ich dem Code einen Test hinzufügte, um zu überprüfen, ob das funktionierte, habe ich keinen Seed gesetzt. Es vermasselte meine zuvor gespotteten Math.random()
Schnappschüsse. Aber dann, als ich es zu Math.random('mathTest')
änderte, erzeugte es einen neuen Generator, der "mathTest" genannt wurde und hörte ab, die Reihenfolge vom Standard abzufangen.
Ich habe auch crypto.randomBytes
für mein Passwort Salze verspottet. Wenn ich also den Code schreibe, um meine Salze zu erzeugen, schreibe ich vielleicht crypto.randomBytes(32, 'user sign up salt').toString('base64')
. Auf diese Weise kann ich ziemlich sicher sein, dass kein nachfolgender Anruf bei crypto.randomBytes
meine Sequenz durcheinander bringt.
Wenn jemand sonst auf diese Weise crypto
spotten möchte, hier ist wie. Diesen Code in <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
Und dann jest.mock('crypto')
einfach anrufen (wieder, ich habe es in einem meiner "Setupfiles"). Seit ich es veröffentlicht habe, ging ich weiter und machte es kompatibel mit der Callback-Methode (obwohl ich nicht die Absicht habe, es so zu benutzen).
Diese beiden Teile des Codes passieren alle 17 von these tests (I __clearChances__
Funktionen für die beforeEach()
s erstellt - es löscht nur alle Schlüssel aus dem chances
Hash)
Update: benutze diese für ein paar Tage jetzt und Ich denke, es funktioniert ziemlich gut. Die einzige Sache ist, ich denke, dass vielleicht eine bessere Strategie, um eine Math.useSeed
Funktion zu schaffen wäre, dass an der Spitze der Tests laufen gelassen, die Math.random
Was glauben Sie, "Test ... dieser Ausgang ist zufällig" bedeutet sogar? Wirf eine Münze und du könntest zweimal hintereinander Köpfe bekommen; Wenn das nicht möglich ist, ist es nicht zufällig. Der Punkt "zufällig" ist * Sie wissen nicht, welchen Wert Sie suchen *. In der Praxis könnten Sie die Funktion zweimal für die gleiche Eingabe ausführen und unterschiedliche Ausgaben erwarten, aber einige (sehr niedrige) Prozentsätze der Zeit, die es sogar mit funktionierendem Code ausfallen sollte. –
Sicher, Test Zufälligkeit ist ein Unsinn. Ich frage, wie man solche Fälle prinzipiell testen kann. Ich habe nur keine Ahnung, wie das geht. –
Der Schlüssel ist hier Test, keine Zufälligkeit. Vielleicht muss der zufällige Teil weggelassen werden oder so. Ich bin ein Noob beim Testen, also habe eine noob Frage. –