Как использовать Jest для тестирования функций с помощью crypto или window.msCrypto

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
17
0
10 579
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

Это должно сработать. Используйте следующий код для глобальной настройки свойства crypto. Это позволит Jest получить доступ к window.crypto и не вызовет никаких проблем.

const crypto = require('crypto');

Object.defineProperty(global.self, 'crypto', {
  value: {
    getRandomValues: arr => crypto.randomBytes(arr.length)
  }
});

Это кажется таким простым, но для меня не работает; мой тест продолжает терпеть неудачу с тем же сообщением crypto.getRandomValues ​​() - not-supported. Есть ли общие ошибки для этого?

RwwL 27.04.2020 01:43

@RwwL попробуйте global.crypto = crypto

Erik Aronesty 09.07.2020 00:08

Как насчет тонкости криптовалюты? Вы можете привести пример, который расширяет ваш ответ, например, когда вам нужно сгенерировать пару криптографических ключей или около того.

Paul Meyer 15.03.2021 16:50

Привет, я тоже застрял в той же проблеме с crypto.subtle.digest, может кто-нибудь помочь?

Hari Om 19.08.2021 09:59

Добавьте 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"],
};

Вы спасли мне жизнь, добавив это в файлы настроек, тестовые файлы, развеселите моего мужчину

Mese 26.02.2021 11:18

@mitchelc Я получил эту ошибку после настройки этого «TypeError: crypto.getRandomValues ​​не является функцией».

Yatin Mistry 17.08.2021 14:06

Для 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), и это то, что у меня сработало. Спасибо!

Ann Kilzer 04.08.2021 11:14

Зависимость 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 },
})

Другие вопросы по теме