node.js - fs readFile をモックすると、プリミティブ値で Cannot spyOn が返されます。未定義の与えられた

okwaves2024-01-25  9

方法は単純です:

import fs from 'fs';
function getFile(path) {
  return new Promise(function(resolve, reject) {
    fs.readFile(path, 'utf8', function(err, success) {
      if (err) reject(err);
      else resolve(success);
    });
  });
}

他のメソッドから呼び出されていますが、readFile をモックする必要があり、3 つのオプションを試しましたが、すべてエラーが発生しました。

1 つを試してください:

  it('should get data', async () => {

    const spy = jest.spyOn(fs,'readFile')
    .........
    });

エラーのある行で停止します:

プリミティブ値をスパイすることはできません。未定義の指定

2 つ試してください:

  let readFileCallback;

  jest.spyOn(fs, 'readFile').mockImplementation((path, options, callback) => {
    readFileCallback = callback;
  });

オプションパラメータが原因で実装エラーがスローされます。

タイプ '(パス: 任意、オプション: 任意、コールバック: 任意) の引数 => void' は、タイプ '(パス: 文字列 | 数値 | バッファ | URL、コールバック: (エラー: ErrnoException、データ: バッファ) => void) => のパラメータには割り当てられません。無効です。

オプション パラメータを削除すると、同じエラーが発生します:

プリミティブ値をスパイすることはできません。未定義の指定

readFile をモックして返すにはどうすればよいですか何かテキストはありますか?



------------------------

jest.spyOn(object, methodName) は機能するはずです。 2 回目の挑戦はもうすぐそこです。 TypeScript の型の問題に直面しています。この型の問題を解決するには、型アサーションを使用してこれを処理できます。

index.ts:

import fs from 'fs';

function getFile(path): Promise<string> {
  return new Promise(function(resolve, reject) {
    fs.readFile(path, 'utf8', function(err, success) {
      if (err) {
        reject(err);
      } else {
        resolve(success);
      }
    });
  });
}

export { getFile };

index.test.ts:

import fs, { PathLike } from 'fs';
import { getFile } from './';

describe('63748243', () => {
  it('should read file', async () => {
    const readFileSpy = jest.spyOn(fs, 'readFile').mockImplementation(((
      path: PathLike | number,
      options: { encoding?: null; flag?: string } | undefined | null,
      callback: (err: NodeJS.ErrnoException | null, data: string) => void,
    ) => {
      if (typeof options === 'string' && options === 'utf8') {
        callback(null, '123');
      }
    }) as typeof fs.readFile);
    const actual = await getFile('/fake/path');
    expect(actual).toEqual('123');
    expect(readFileSpy).toBeCalledWith('/fake/path', 'utf8', expect.any(Function));
    readFileSpy.mockRestore();
  });
});

単体テストの結果とカバレッジ レポート:

 PASS  src/stackoverflow/63748243/index.test.ts (8.99s)
  63748243
    ✓ should read file (6ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |    85.71 |       50 |      100 |    85.71 |                   |
 index.ts |    85.71 |       50 |      100 |    85.71 |                 7 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.04s

ソース コード: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/63748243

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。