При запуске модульных тестов с Jest в реакции API window.crypto вызывает проблемы. Я не нашел способа включить криптовалюту в Jest без установки других пакетов, чего я не могу сделать. Итак, без использования другого пакета npm, есть ли способ протестировать функции, которые используют: crypto.getRandomValues() в них, что не приводит к сбою Jest? Любые ссылки, советы или подсказки приветствуются.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это должно сработать. Используйте следующий код для глобальной настройки свойства crypto. Это позволит Jest получить доступ к window.crypto и не вызовет никаких проблем.
const crypto = require('crypto');
Object.defineProperty(global.self, 'crypto', {
value: {
getRandomValues: arr => crypto.randomBytes(arr.length)
}
});
@RwwL попробуйте global.crypto = crypto
Как насчет тонкости криптовалюты? Вы можете привести пример, который расширяет ваш ответ, например, когда вам нужно сгенерировать пару криптографических ключей или около того.
Привет, я тоже застрял в той же проблеме с crypto.subtle.digest, может кто-нибудь помочь?
Добавьте crypto global для вашей среды шуток, как если бы он был в браузере.
Ваш jest.config.js должен выглядеть так:
const {defaults} = require('jest-config');
module.exports = {
globals: {
...defaults.globals,
crypto: require('crypto')
}
};
Ссылка: https://jestjs.io/docs/en/configuration#globals-object
Как и @RwwL, принятый ответ у меня не сработал. Я обнаружил, что полифилл, используемый в этой библиотеке, действительно работает: совершить с помощью полифилла
//setupTests.tsx
const nodeCrypto = require('crypto');
window.crypto = {
getRandomValues: function (buffer) {
return nodeCrypto.randomFillSync(buffer);
}
};
//jest.config.js
module.exports = {
//...
setupFilesAfterEnv: ["<rootDir>/src/setupTests.tsx"],
};
Вы спасли мне жизнь, добавив это в файлы настроек, тестовые файлы, развеселите моего мужчину
@mitchelc Я получил эту ошибку после настройки этого «TypeError: crypto.getRandomValues не является функцией».
Для nodeJS + typescript просто используйте global вместо global.self
import crypto from 'crypto'
Object.defineProperty(global, 'crypto', {
value: {
getRandomValues: (arr:any) => crypto.randomBytes(arr.length)
}
});
У меня есть эта проблема в Angular 8 с тестами Jest для lib, которые используют генератор uuid. В шутливой тестовой настройке я издеваюсь над этим:
Object.defineProperty(global.self, 'crypto', {
value: {
getRandomValues: arr => arr
},
});
const crypto = require('crypto');
global.crypto = crypto;
Начиная с узла 15.x вы можете использовать crypto.webcrypto
например.
import crypto from "crypto";
Object.defineProperty(global.self, "crypto", {
value: {
subtle: crypto.webcrypto.subtle,
},
});
Исходя из ответа AIVeligs:
Поскольку в Jest я использую среду "node", мне пришлось использовать
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
globals: {
crypto: {
getRandomValues: (arr) => require("crypto").randomBytes(arr.length),
},
},
};
Я использую vue-jest, и у меня сработала следующая конфигурация в файле jest.config.js:
module.exports = {
...
setupFiles: [
'<rootDir>/tests/settings/jest.crypto-setup.js',
],
};
и в jest.crypto-setup.js:
global.crypto = {
getRandomValues: (arr) => require('crypto').randomBytes(arr.length)
};
Добавление определения функции getRandomValues непосредственно в module.exports не сработало, поскольку объект globals должен быть json-сериализуемым (как указано здесь: https://jestjs.io/docs/configuration#globals-object).
Я пробовал много решений (с использованием React + TS), и это то, что у меня сработало. Спасибо!
Зависимость crypto по умолчанию у меня не работала во время тестирования с Jest.
Вместо этого я использовал библиотеку @peculiar/webcrypto:
yarn add -D @peculiar/webcrypto
Затем в вашем установочном файле Jest просто добавьте это:
import { Crypto } from "@peculiar/webcrypto";
window.crypto = new Crypto();
Полифиллы в текущих ответах неполные, поскольку Crypto.getRandomValues() изменяет свой аргумент на месте, а также возвращает его. Вы можете проверить это, запустив что-то вроде const foo = new Int8Array(8); console.info(foo === crypto.getRandomValues(foo)) в консоли вашего браузера, которая напечатает true.
getRandomValues() также не принимает Array в качестве аргумента, он принимает только целое число TypedArrays. Функция crypto.randomBytes() в Node.js не подходит для этого полифилла, поскольку она выводит необработанный байты, тогда как getRandomValues() может принимать массивы целых чисел со знаком с элементами до 32 бит. Если вы попробуете crypto.getRandomValues(new Int32Array(8)) в своем браузере, вы можете увидеть что-то вроде [ 304988465, -2059294531, 229644318, 2114525000, -1735257198, -1757724709, -52939542, 486981698 ]. Но если вы попробуете node -e 'console.info([...require("crypto").randomBytes(8)])' в командной строке, вы можете увидеть [ 155, 124, 189, 86, 25, 44, 167, 159 ]. Ясно, что они не эквивалентны, и ваш тестируемый компонент может вести себя не так, как ожидалось, если тестируется с последним.
Последние версии Node.js решают эту проблему с помощью webcrypto модуль (это должно быть связано с настройкой globalThis.crypto = require('crypto').webcrypto). Если вы используете старую версию Node (v14 или ниже), возможно, вам больше повезет с использованием crypto.randomFillSync(), который следует использовать в качестве замены для getRandomValues(), поскольку он изменяет переданный буфер / TypedArray на месте.
В вашем установочном файле Jest (не может быть установлен через Конфигурация globals, поскольку он допускает только JSON-совместимые значения):
const { randomFillSync } = require('crypto')
Object.defineProperty(globalThis, 'crypto', {
value: { getRandomValues: randomFillSync },
})
Это кажется таким простым, но для меня не работает; мой тест продолжает терпеть неудачу с тем же сообщением crypto.getRandomValues () - not-supported. Есть ли общие ошибки для этого?