1

I had trouble testing my code that implement sharp and memfs. I has codes that download image and cropping it to certain dimension. I use sharp to achieve the cropping. When it comes testing, I use jest and memfs. My test code has 2 parts:

  1. Download a image and save to mock volume/fileSystem that created with memfs.
  2. Cropping the downloaded image to certain dimension with sharp.

Part 1 worked perfectly, was able to download image to the fake volume and asserted with jest (exist in the fake volume).
But part 2 gave me error:[Error: Input file is missing].

const sizeToCrop = {
            width: 378,
            height: 538,
            left: 422,
            top: 0,
        };

sharp(`./downloadedImage.jpg`)
            .extract(sizeToCrop)
            .toFile(`./CroppedImage.jpg`)
            .then(() => {
                console.log(`resolve!`);
            })
            .catch((err: Error) => {
                console.log(err);
                return Promise.reject();
            });

// Error message: [Error: Input file is missing]

But when I test it with real volume. It worked fine.
Anyone has idea how to solve this? Thank you.

koonfoon
  • 433
  • 4
  • 12

1 Answers1

1

After some inspirations from here, here and here.

It is because sharp is not accessing memfs' faked file system, it is accessing the actual fs' file system, which ./donwloadedImage.jpg to not exist. Hence, in order to make sharp use memfs, it has to be mocked. And extract and toFile functions need to be mocked as well(for chaining function call):

// Inside code.test.ts

jest.mock('sharp', () => {
    const sharp = jest.requireActual('sharp');
    const { vol } = require('memfs');
    let inputFilePath: string;
    let sizeToCrop: any;
    let outputFilePath: string;
    const toFile = async (writePath: string): Promise<any> => {
        outputFilePath = writePath;
        try {
            return await starCropping();
        } catch (error) {
            console.log(`Error in mocked toFile()`, error);
        }
    };
    const extract = (dimensionSize: string): any => {
        sizeToCrop = dimensionSize;
        return { toFile };
    };
    const mockSharp = (readPath: string): any => {
        inputFilePath = readPath;
        return { extract };
    };
    async function starCropping(): Promise<void> {
        try {
            const inputFile = vol.readFileSync(inputFilePath);
            const imageBuffer = await sharp(inputFile).extract(sizeToCrop).toBuffer();
            vol.writeFileSync(outputFilePath, imageBuffer);
        } catch (error) {
            console.log(`Error in mocked sharp module`, error);
            return Promise.reject();
        }
    }

    return mockSharp;
});
koonfoon
  • 433
  • 4
  • 12