source

암호 또는 window.msCrypto를 사용하여 함수를 테스트하는 방법

bestscript 2023. 3. 1. 11:15

암호 또는 window.msCrypto를 사용하여 함수를 테스트하는 방법

를 반응시킵니다.window.cryptoAPI를 사용합니다.난 아직 이 모든 것을 통합시킬 방법을 찾지 못했다.cryptoJest에서 다른 패키지를 설치하지 않고 작업을 수행할 수 없습니다. 다른 하지 않고 같은 .crypto.getRandomValues()스트트 충돌 ?? ????은 모두 합니다.

하여 을 합니다.crypto글로벌하게 확장됩니다. 제스트가 할 수 있게 .

  • window.crypto
  • global.crypto(노드/타입 스크립트)입니다.

현재 대부분의 최신 브라우저와 Node.js 12+에서 사용할 수 있는를 사용합니다.

const crypto = require('crypto');

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

@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"],
};

의 경우+ JS + js js js js js js js, js js js js js js만 사용하세요.globalglobal.self

import crypto from 'crypto'

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

15에서는, 「15.x」를 사용할 수 .crypto.webcrypto

예:

import crypto from "crypto";

Object.defineProperty(global.self, "crypto", {
  value: {
    subtle: crypto.webcrypto.subtle,
  },
});

합니다.Crypto.getRandomValues()는 인수를 in-place로 변경할 뿐만 아니라 반환할 수도 있습니다.할 수 은 '알겠습니다' 같은 것을 해 보세요.const foo = new Int8Array(8); console.log(foo === crypto.getRandomValues(foo))" " " " 라고 됩니다.true.

getRandomValues()또, 에는 대응하고 있지 않습니다.Array인수로서 정수 s만을 받아들입니다.Node.js'crypto.randomBytes()이 폴리필에는 미가공 바이트를 출력하기 때문에 이 함수는 적합하지 않습니다.getRandomValues()는 최대 32비트의 요소를 가진 부호 있는 정수 배열을 받아들일 수 있습니다.crypto.getRandomValues(new Int32Array(8)), 하다, 하다, 하다' 이런 게 도 있어요.[ 304988465, -2059294531, 229644318, 2114525000, -1735257198, -1757724709, -52939542, 486981698 ] 만약 이 시도한다면node -e 'console.log([...require("crypto").randomBytes(8)])''명령하다'라고 수 있습니다.[ 155, 124, 189, 86, 25, 44, 167, 159 ]이들 컴포넌트가 동등하지 않은 것은 분명하며 테스트 대상 컴포넌트는 후자를 사용하여 테스트하면 예상대로 동작하지 않을 수 있습니다.

최신 버전의 Node.js는 모듈에서 이 문제를 해결합니다(설정에 따라 다름).globalThis.crypto = require('crypto').webcrypto오래된 버전의 노드(v14 이하)를 사용하고 있는 경우는, 를 사용하는 것이 좋을 가능성이 있습니다.이것은, 의 드롭 인 교환용으로 사용할 수 있습니다.getRandomValues() buffer/suffersuffer/suffer/suffer/suffer/suffer/suffer/TypedArray인플레이스

Jest 설정 파일(JSON 호환 값만 허용하므로 구성을 통해 설정할 수 없음):

const { randomFillSync } = require('crypto')

Object.defineProperty(globalThis, 'crypto', {
  value: { getRandomValues: randomFillSync },
})

AIVeligs에서 도출한 답변:

Jest에서 "노드" 환경을 사용하기 때문에

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 the the didn didn didn didn 。globals오브젝트는 json-companizable이어야 합니다(여기서 지정되어 있습니다.https://jestjs.io/docs/configuration#globals-object) ).

crypto브라우저에 있는 것과 같은 농담 환경에 대해 글로벌하게 설명합니다.jokejoke.config.js 。

const {defaults} = require('jest-config');

module.exports = {
  globals: {
    ...defaults.globals,
    crypto: require('crypto')
  }
};

참고 자료: https://jestjs.io/docs/en/configuration#globals-object

이 문제는 uuid 생성기를 사용하는 lib의 Angular 8 with Jest 테스트에서 발생합니다.농담 테스트 설정에서 나는 이것을 조롱한다.

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

★★★★★★★★★★★★★★★★★★★★★★★★★.jsdom )jest-environment-jsdom가 있는 Jest >=28교체 모듈을 getter로 정의해야 합니다.

//jest.config.js
module.exports = {
  testEnvironment: "jsdom",
  rootDir: './',
  moduleFileExtensions: ['ts', 'js'],
  setupFilesAfterEnv: ["<rootDir>/test/setup-env.tsx"],
  preset: 'ts-jest',
};
// setup-env.tsx
const { Crypto } = require("@peculiar/webcrypto");
const cryptoModule = new Crypto();

Object.defineProperty(window, 'crypto', {
  get(){
    return cryptoModule
  }
})

하고 .@peculiar/webcrypto지른

" " "crypto제스트와 함께 테스트하는 동안 의존성이 통하지 않았어요.

★★★★★★★★★★★★★★★★★★★를 사용했습니다.@peculiar/webcrypto★★★★★★★★★★★★★★★★★★:

yarn add -D @peculiar/webcrypto

그런 다음 Jest 설정 파일에 다음을 추가합니다.

import { Crypto } from "@peculiar/webcrypto";


window.crypto = new Crypto();

dspacejs의 답변은 거의 먹혀들었지만, Mozgor와 같은 문제가 있었다.window.crypto가 읽기 전용이라는 오류가 발생했습니다.Object.assign을 직접 덮어쓰지 않고 사용할 수 있습니다.

@pequalious/를 @와 함께 yarn add -D @peculiar/webcrypto ★★★★★★★★★★★★★★★★★」npm i --save-dev @peculiar/webcrypto

그런 다음 다음 Jest 설정 파일에 다음을 추가합니다.

import { Crypto } from "@peculiar/webcrypto";

Object.assign(window, {
  crypto: new Crypto(),
})
const crypto = require('crypto');
global.crypto = crypto;

디폴트 설정에서는 Jest는 Node.js 환경을 테스트하고 있다고 가정합니다.단, 에러가 발생했을 때는window오브젝트, 아마 웹 앱을 만들고 있을 거예요.

따라서 웹 앱을 만드는 경우 "테스트 환경"으로 "jsdom"을 사용해야 합니다.이를 수행하려면 Jest 구성에 삽입하십시오.

"jest.config.js" 파일을 유지할 경우 다음과 같이 추가합니다.

module.exports = {
   ...
   "testEnvironment": "jsdom",
   ...
};

또는 나처럼 Jest 설정을 "package.json"으로 유지하는 경우:

{
    ...,
    "jest": {
        ...,
        "testEnvironment": "jsdom",
        ...
    },
    ...
}

다른 사람의 의견을 바탕으로 다음과 같이 window.crypto.subtle.digest 문제를 해결했습니다.

Object.defineProperty(global.self, "crypto", {
  value: {
    getRandomValues: (arr: any) => crypto.randomBytes(arr.length),
    subtle: {
      digest: (algorithm: string, data: Uint8Array) => {
        return new Promise((resolve, reject) =>
          resolve(
            createHash(algorithm.toLowerCase().replace("-", ""))
              .update(data)
              .digest()
          )
        );
      },
    },
  },
});

또는 Typescript를 사용하지 않는 경우:

Object.defineProperty(global.self, "crypto", {
  value: {
    getRandomValues: (arr) => crypto.randomBytes(arr.length),
    subtle: {
      digest: (algorithm, data) => {
        return new Promise((resolve, reject) =>
          resolve(
            createHash(algorithm.toLowerCase().replace("-", ""))
              .update(data)
              .digest()
          )
        );
      },
    },
  },
});

문자열 재구성은 옵션입니다.예를 들어 'sha256' 또는 'sha512' 또는 이와 유사한 명령어를 사용하여 알고리즘을 하드코딩할 수도 있습니다.

문제를 해결하는 방법 중 하나는 디스펜시 주입입니다.

Node.js는 표준 Web Crypto API를 구현합니다.require('node:crypto')를 사용합니다.webcrypto를 사용하여 이 모듈에 액세스합니다.

따라서 crypto 오브젝트를 종속된 코드에 전달합니다.

" " " " " " 를 때 를 "하십시오.utils.aesGcmEncrypt

test("Encrypt and decrypt text using password", async () => {
  const password = "Elvis is alive";
  const secret =
    "surprise action festival assume omit copper title fit tower will chalk bird";
  const crypto = require("crypto").webcrypto;
  const encrypted = await utils.aesGcmEncrypt(crypto, secret, password);
  const decrypted = await utils.aesGcmDecrypt(crypto, encrypted, password);

  expect(decrypted).toBe(secret);
});

파티에 늦었지만, 저는 보통 이렇게 해요.

// module imports here
// important: the following mock should be placed in the global scope

jest.mock('crypto', function () {
  return {
    randomBytes: jest
      .fn()
      .mockImplementation(
        () =>
          'bla bla bla'
      ),
  }
});

describe('My API endpoint', () => {
  it('should work', async () => {
    const spy = jest.spyOn(DB.prototype, 'method_name_here');
    // prepare app and call endpoint here
    expect(spy).toBeCalledWith({ password: 'bla bla bla' });
  });
});

언급URL : https://stackoverflow.com/questions/52612122/how-to-use-jest-to-test-functions-using-crypto-or-window-mscrypto