How to mock and test fs.createReadStream with jest?

220 views Asked by At

I have a function in which I use fs.createReadStream, I want to mock it so I can test, for example, that the functionTest is being called on receiving data and the functionTest2 is being called on stream's end.

The code is something like this:

const readStream = fs.createReadStream(filePath, { highWaterMark: 260 * 1000 });

  readStream.on("data", (chunk) => {
    functionTest();
  });
  readStream.on("end", (chunk) => {
    functionTest2("example")
  });

I have take a look inte mock-fs and memfs, but honestly Im very confused and don't know which is te correct path to follow

1

There are 1 answers

0
Tamil Vendhan Kanagarasu On

In order to make the function testable, I would split it in to two parts:

  1. A function that returns the stream - I can test this by checking the return value instance
  2. A function that handles the stream - I can test this by passing readable stream
function getFileStream() {
  return fs.createReadStream(filePath, { highWaterMark: 260 * 1000 });
}

function handleStream(readStream, dataCallback, endCallback) {
  readStream.on("data", (chunk) => {
    dataCallback();
  });
  readStream.on("end", (chunk) => {
    endCallback("example")
  });
}

function handleFile(filePath, dataCallback, endCallback) {
  const stream = getFileStream(filePath);
  handleStream(stream, dataCallback, endCallback);
}

...
...
// In test file

const dataCallback = jest.fn(...);
const endCallback = jest.fn(...);
test('Expect callbacks to be called once', () => {
  const readable = stream.Readable({
    read() {}
  });
  
  handleStream(readable, dataCallback, endCallback);

  readable.push('Hello'); // Emits data event
  readable.push(null); // Emits end event

  expect(dataCallback.mock.calls).toHaveLength(1);
  expect(endCallback.mock.calls).toHaveLength(1);


});