簡體   English   中英

使用 Jest 和 mock-fs 測試 async fs.readfile 會使測試超時,即使超時 30 秒

[英]Testing async fs.readfile with Jest and mock-fs has the tests timing out, even with 30 second time out

我有一個函數,它使用 Node 的 fs 從文件系統異步讀取文件的內容。 雖然該功能有效,但我無法使用 Jest 對其進行測試。 我正在使用 mock-fs 庫來模擬文件系統以嘗試測試該功能。

讀取文件的函數:read-file-contents.ts

import * as NodeJSFS from 'fs';
import * as NodeJSPath from 'path';

export async function ReadFileContents(Directory:string, FileName:string):Promise<string> {
    return new Promise<string>((resolve, reject) => {
        const PathAndFileName = NodeJSPath.format( { dir: Directory, base: FileName });

        NodeJSFS.readFile(
            PathAndFileName,
            (error: NodeJS.ErrnoException | null, FileContents: Buffer) => {
                if (error) {
                    reject(error);
                } else {
                    resolve(FileContents.toString());
                }
            },
        );
    });
}

由於 mock-fs 中有一個目錄和一個文件,測試文件確實讓 mock-fs 工作,因為文件計數被正確返回。 錯誤處理例程工作並捕獲未找到處理的文件,然后通過。

但是,從模擬中讀取實際文件的測試失敗了。 讀取文件內容.spec.ts

import * as MockFS from 'mock-fs';
import { ReadFileContents } from './read-file-contents';

describe('ReadFileContents', () => {
    afterEach( () => {
        MockFS.restore();
    });
    beforeEach( () => {
        MockFS( {
            'datafiles': {
                'abc.txt': 'Server Name'
            }
        }, {
            // add this option otherwise node-glob returns an empty string!
            createCwd: false
        } );
    });

    it('should have the proper number of directories and files in the mocked data', () => {
        expect(MockFS.length).toBe(2);
    });

    it('should error out when file does not exist', async () => {
        try {
            await ReadFileContents('./', 'file-does-not.exist');
        } catch (Exception) {
            expect(Exception.code).toBe('ENOENT');
        }
    });

    it('should load the proper data from abc.txt', async () => {
        let FileContents:string;
        try {
            FileContents = await ReadFileContents('./datafiles', 'abc.txt');
            expect(FileContents).toBe('Server Name');
        } catch (Exception) {
            console.log(Exception);
            expect(true).toBeFalsy();   // Should not happen due to mock-fs file system
        }
    });
});

最后一次測試未在 30 秒內返回並出現以下錯誤:

 FAIL  src/library/file-handling/read-file-contents.spec.ts (57.175 s)
  ● ReadFileContents › should load the proper file data abc.hdr

    thrown: "Exceeded timeout of 30000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

  22 |      });
  23 |
> 24 |      it('should load the proper file data abc.hdr', async () => {
     |      ^
  25 |              let FileContents:string;
  26 |              try {
  27 |                      FileContents = await ReadFileContents('./datafiles', 'abc.hdr' );

在尋求更多幫助時,我找到了解決方案。 我目前使用的是 Node 15.9,從 Node 10(或 12 無論如何)開始,promises 庫可以更好地處理 fs 函數。

因此,我的 ReadFileContents() 代碼變得更加簡單,因為我可以簡單地使用 fs/promises 中 FS readFile 的承諾版本。 這樣就會拋出錯誤,或者異步讀取文件,使用這個函數的代碼,已經有了try/catch,將處理數據或捕獲拋出的錯誤。

import * as NodeJSFSPromises from 'fs/promises';
import * as NodeJSPath from 'path';

export async function ReadFileContents(Directory:string, FileName:string):Promise<string> {
    const PathAndFileName = NodeJSPath.format( { dir: Directory, base: FileName });
    const FileContents$:Promise<Buffer> = NodeJSFSPromises.readFile(PathAndFileName);
    const Contents:string = (await FileContents$).toString();
    return Contents;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM