erakis
erakis

Reputation: 60

Stub a module which exports a function

I need to replace the function returns by a module.

I'm using CommonJS with nodejs 18.

index.js

const sinon = require("sinon");
const axios = require("axios");
const fs = require("fs");

const fileConverter = require("./file-converter");

async function main() {
  // Anyway, here is the way I did it for now:
  sinon.stub(fs.promises, "readFile").withArgs("test").returns("File content");

  sinon
    .stub(axios, "get")
    .withArgs("/codec-parameters?type=json")
    .resolves("File decoder");

  const result = await fileConverter.fromFilePath("test");
  console.log(result);
}

main();

file-converter.js

const getCodec = require("./file-converter-codec");
const fs = require("fs");

class FileConverter {
  #codecs;

  #filePath;

  constructor(filePath) {
    this.#filePath = filePath;
  }

  async convert() {
    const fileContent = await fs.promises.readFile(this.#filePath);
    const codec = await getCodec("json");
    return codec.decode(fileContent);
  }
}

async function fromFilePath(filePath) {
  const fileParsed = new FileConverter(filePath);
  return await fileParsed.convert();
}

module.exports = {
  fromFilePath,
};

file-converter-codec.js

const axios = require("axios");

class FileConverterCodec {
  #parameters;

  constructor(parameters) {
    this.#parameters = parameters;
  }

  decode(data) {
    return "File has been decoded";
  }
}

module.exports = async (type) => {
  const parameters = await axios.get(`/codec-parameters?type=${type}`);
  return new FileConverterCodec(parameters);
};

How can I stub the getCodec method that is called from inside of the class FileConverter? As the class FileConverter is not exported, I don't know how to do it. I want to prevent it from calling a REST API dependency

Is my reasoning correct if I include Axios directly here and stub it before it gets required from the file-converter-codec.js? I didn't want to stub Axios directly, which is called 2 modules deeper.

I prefer to stub a level under the file to be tested, no more! Otherwise, unit testing would require examining very deeply the sparse code in the case of a huge project. Is it correct? If it's correct then how can I stub a module that exports a function directly, like the one in the file-converter-codec.js?

Codesandbox of this example

Note that I cannot modify the source code of the required module to add a name to it. Otherwise, I would have already done it.

Upvotes: 0

Views: 51

Answers (0)

Related Questions