[Jest]TypeError: Cannot read property 'readFileSync' of null

5146 단어 Jest

Overview



Jest에서 테스트를 실행할 때 다음 오류가 발생했습니까?
만약 당신이 esm 패키지를 이용한다면, 나는 그 문제에 대한 완화책을 제시할 수 있을 것이다.
TypeError: Cannot read property 'readFileSync' of null

      at fetch (node_modules/protobufjs/src/root.js:160:34)
      at Root.load (node_modules/protobufjs/src/root.js:194:13)
      at Root.loadSync (node_modules/protobufjs/src/root.js:235:17)
      at Object.loadSync (node_modules/protobufjs/src/index-light.js:69:17)
      at Object.<anonymous> (node_modules/@grpc/proto-loader/build/src/index.js:235:37)


Target reader


  • 위의 오류가 발생한 사람.

  • Prerequisite


  • Node.js v10.19.0
  • esm 패키지 사용

  • Body



    Jest와 esm의 관계에 대해 조금 언급



    Jest는 import/export의 양식에 쓰기 시점에서는 대응하고 있지 않다.
    즉 import/export의 기술을 가능하게 하는 esm과는 궁합이 나쁘다.
    그 근처에 대해 알고 싶다면 다른 기사를 참조하십시오.
    htps : // 이 m/q 루사도 r·있어 ms/f637953c0 아다 73483700 9% 96% 2% 3% 81% 99% 3% 82% 8B% 6% B3% 8% 6% 84% 8F% 7% 82% B9

    esm을 node 명령으로 실행하거나 서버리스 Functions에서 실행하는 분에는 문제 없다.
    그것은 나 자신 esm를 진짜로 소개를 완료하고 사실에 근거한 할말이다.
    그러나 Jest만은 아무래도 안 된다

    일단 이번 문제는 issue에 오르고 있다.
    htps : // 기주 b. 이 m / s 단지 rd-te gs / 에 sm / 이스에 s / 779

    미묘하게 다르게 보일지도 모르지만 근본 원인은 함께라고 생각하고 있다.
    아마 이 문제는 당분간은 해결되지 않을 것이기 때문에 완화책을 모색했다.

    import 문을 포기



    인간 당겨 판단이 중요. 다행히 esm은 require를 혼재해 사용해도 OK이므로, 에러가 발생하는 해당 소스는 require 그대로 둔다.
    프로덕션이라면 그것만으로 OK이지만, Jest는 esm의 앞에 있는 에러가 발생하는 패키지의 require를 허락해 주지 않는다
    상상이 되지만, 각 테스트의 소스 코드 서두에 둔다 const requireEsm = require('esm')(module);
    가 require 를 옮겨, Jest 환경하에서는 잘 가지 않는 것일 것이다.

    이 생각하에 회피 처리를 만들면 잘 간다.
    우선은 에러가 발생하는 테스트 코드의 1행째를 다음과 같이 한다.

    hoge.test.js
    global.requireJest = require; // ★esmが置き換える前のもとのrequireを保存しておく
    
    // 通常はここが1行目で、esmのrequireを使用するだけでOK。
    const requireEsm = require('esm')(module);
    const { objectToArray } = requireEsm('../../utils/object')
    

    네이밍은 중복하지 않으면 무엇이든 좋지만, 여기에서는 requireJest로서 본래의 require를 global에 보존한다.
    다음에 에러가 발생하는 import 부분에 대응을 넣는다.
    실제로 에러가 발생한 firebase-admin의 패키지에 대응한 예를 게재한다.

    firebaseAdmin.js
    // import admin from 'firebase-admin'; // 残念ながらJestではエラーになる
    const admin = global.requireJest ? requireJest('firebase-admin') : require('firebase-admin'); // for jest test
    

    앞에서 global.requireJest 에 보존한 require가 있다면 그쪽을 이용해, 없으면 프로덕션 환경이므로 통상의 require를 사용한다.
    이것으로 프로덕션에서도 Jest에서 어느 쪽이든 움직일 수 있습니다.

    Conclusion



    esm에 의해 import/export가 사용 가능하게 되어 편리하지만, 마지막으로 Jest의 함정이 있다.
    그 개소만 import를 포기하면 완수할 수 있기 때문에, 포기하지 말라는 이야기였습니다.

    덧붙여서 내가 단번에 이행했을 때, firebaseAdmin.js를 참조하고 있는 테스트가 모두 안 되었다.
    스택 추적에서 firebaseAdmin.js에서 발생했다는 것을 알 수 없기 때문에 판명하는 데 시간이 걸렸습니다.
    (치마치마 스텁으로 바꾸어 import문 하나하나 찾았다 )

    Have a great day!

    좋은 웹페이지 즐겨찾기