使用 Jest 和 mock-fs 测试异步 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 库来模拟文件系统以尝试测试功能。
读取文件的函数:
读取文件-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 工作,因为文件计数是 returned 正确,由于 mock-fs 中的目录和文件。错误处理例程工作并捕获未找到的文件处理,并通过。
但是,从模拟中读取实际文件的测试失败了。
读取文件-contents.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
}
});
});
上次测试没有 return 超时 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;
}
我有一个函数可以使用 Node 的 fs 从文件系统异步读取文件的内容。虽然该功能有效,但我无法使用 Jest 对其进行测试。我正在使用 mock-fs 库来模拟文件系统以尝试测试功能。
读取文件的函数: 读取文件-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 工作,因为文件计数是 returned 正确,由于 mock-fs 中的目录和文件。错误处理例程工作并捕获未找到的文件处理,并通过。
但是,从模拟中读取实际文件的测试失败了。 读取文件-contents.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
}
});
});
上次测试没有 return 超时 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;
}