【问题标题】:Testing async fs.readfile with Jest and mock-fs has the tests timing out, even with 30 second time out使用 Jest 和 mock-fs 测试 async fs.readfile 会导致测试超时,即使超时 30 秒
【发布时间】:2021-09-10 08:24:22
【问题描述】:

我有一个使用 Node 的 fs 从文件系统异步读取文件内容的函数。虽然该功能有效,但我无法使用 Jest 对其进行测试。我正在使用 mock-fs 库来模拟文件系统以尝试测试功能。

读取文件的函数: 读取文件内容.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.js unit-testing jestjs mock-fs


    【解决方案1】:

    在寻求更多帮助时,我找到了解决方案。我目前使用的是 Node 15.9,并且由于 Node 10(或无论如何是 12),promise 库可以更好地处理 fs 函数。

    因此,我的 ReadFileContents() 代码变得更加简单,因为我可以简单地使用来自 fs/promises 的 FS readFile 的 promise 版本。这样会抛出错误,或者异步读取文件,使用这个函数的代码,已经有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;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-02
      • 2020-09-02
      • 2018-06-03
      • 2017-04-07
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 2011-07-04
      • 1970-01-01
      相关资源
      最近更新 更多