The fs.Dirent class constructor is undocumented, along with the UV_DIRENT_-prefixed constants. Having these documented would greatly ease the developer experience when writing tests that mock or spy on fs operations made by the user application.
constructor
constants
The UV_* constants are implementation details, that's also why the type is stored as a symbol rather than a property.
when writing tests that mock or spy on fs operations
I'm not following. What exactly are you doing with fs.readdir() that requires you to create your own fs.Dirent instances?
What exactly are you doing with fs.readdir() that requires you to create your own fs.Dirent instances?
I have a function called listDirectoryFiles that uses fs.readDir() to iterate and filter results. In our test suite we then want to mimic the response from fs.readDir() by mocking it and returning an instance of Dirent that we are able to control the output for, without relying on the actual file system or performing I/O operations:
fsHelpers.js
exports.readDir = require('util').promisify(fs.readDir)
exports.listDirectoryFiles = async (directoryPath) => {
const dirItems = await exports.readDir(directoryPath, { withFileTypes: true })
return dirItems
.filter(item => !item.isDirectory())
.map(item => item.name)
}
(As part of the research I did in writing the ticket and commit referenced above, I realize that the implementation of the filter itself is flawed, but that doesn't change how the test would be written)
fsHelpers.spec.js
One of the tests, written with Jest
it('ignores subdirectories in the supplied directory', async () => {
const { listDirectoryFiles } = jest.requireActual('./fsHelpers')
const { Dirent, constants } = jest.requireActual('fs')
// Prepare our mock
const directory = new Dirent('directory', constants.UV_DIRENT_DIR)
fs.readdir.mockResolvedValue([ directory ])
// Run the method being tested
const files = await listDirectoryFiles()
// Assertion
expect(files).toMatchObject([])
})
The
UV_*constants are implementation details
I understand that the UV_ constants are inherited from libuv but they are nontheless used to construct the object and exported in fs.constants; while an intermediary enum could be used, I mainly created this ticket to address the documentation of the existing implementation.
W.r.t. to testing/mocking, I don't think it's too onerous to provide your own fs.Dirent implementation. The current status quo is good enough, IMO.
Most helpful comment
The
UV_*constants are implementation details, that's also why the type is stored as a symbol rather than a property.I'm not following. What exactly are you doing with
fs.readdir()that requires you to create your ownfs.Direntinstances?