Node: fs.Dirent constructor is undocumented

Created on 5 May 2020  路  3Comments  路  Source: nodejs/node

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

https://github.com/nodejs/node/blob/c17dcb32533aa007dfbf507d22c28ef3c7c11c29/lib/internal/fs/utils.js#L118-L122

constants

https://github.com/nodejs/node/blob/c17dcb32533aa007dfbf507d22c28ef3c7c11c29/lib/internal/fs/utils.js#L72-L79

Most helpful comment

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?

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sandeepks1 picture sandeepks1  路  3Comments

Icemic picture Icemic  路  3Comments

stevenvachon picture stevenvachon  路  3Comments

willnwhite picture willnwhite  路  3Comments

danialkhansari picture danialkhansari  路  3Comments