previewjs icon indicating copy to clipboard operation
previewjs copied to clipboard

Enable mocking of specific modules

Open fwouts opened this issue 2 years ago • 8 comments

See https://github.com/fwouts/previewjs/discussions/950 for an example where this would be useful, reported by @tvaughan73.

fwouts avatar Aug 18 '22 23:08 fwouts

This would be awesome!

I'm currently running into a scenario where this would be useful. Here's an example from NextJS:

import { prisma } from "#lib/db";

const NotificationPage: NextPage = () => {
  return (
    <PageError
      icon={SadFaceIcon}
      title="Invalid Notification ID"
      message="The target of the notification you are trying to view does not exist or has been removed."
    />
  );
};

export async function getServerSideProps({ query }: NextPageContext) {
  const uuid = String(query.uuid);
  const data = await prisma.notifications.findMany({
    where: {
      id: uuid,
    },
  });

  return {
    props: {
      data
    },
  };
}

export default NotificationPage;

When trying to preview this NextJS component in PreviewJS, I get an error regarding Prisma not being able to run in the browser.

It would be helpful if I could mock the prisma.notifications.findMany function to return a specific array.

jordanarldt avatar Sep 03 '22 05:09 jordanarldt

Thank you @jordanarldt for the example, that's really helpful.

Can you clarify in this particular case, does prisma come from an import or is it somehow in the global scope?

fwouts avatar Sep 03 '22 06:09 fwouts

Thank you @jordanarldt for the example, that's really helpful.

Can you clarify in this particular case, does prisma come from an import or is it somehow in the global scope?

Sure, in my web app, prisma comes from an import from #lib/db (alias for src/lib/db, and here's the contents:


import { PrismaClient } from "@prisma/client";

export const prisma: PrismaClient =
  global.prisma ||
  new PrismaClient({
    log: ["query"],
  });

if (process.env.NODE_ENV !== "production") global.prisma = prisma;

So I do set Prisma in global scope during development to prevent reinstantiating the client, but ultimately every use will simply come from importing the prisma const.

If I could simply mock the Prisma object exported from here, it would make things much easier 🙂

Edit: I updated my original code example to show the import

jordanarldt avatar Sep 04 '22 17:09 jordanarldt

Thanks @jordanarldt!

In this case, I wonder if setting up an alias for this particular module that "redirects it" to a mock implementation wouldn't be enough. See https://previewjs.com/docs/config/aliases

// preview.config.js

module.exports = {
  alias: {
    "#lib/db": "fake-db.js" // or maybe src/lib/db.js?
  }
};

Would this work?

fwouts avatar Sep 04 '22 21:09 fwouts

Thanks @jordanarldt!

In this case, I wonder if setting up an alias for this particular module that "redirects it" to a mock implementation wouldn't be enough. See https://previewjs.com/docs/config/aliases

// preview.config.js

module.exports = {
  alias: {
    "#lib/db": "fake-db.js" // or maybe src/lib/db.js?
  }
};

Would this work?

I did try that in my project, but it didn't seem to work. I'll try it again when I get a chance.

jordanarldt avatar Sep 07 '22 17:09 jordanarldt

Hey again @fwouts I think originally I had my preview.config.js file in the wrong location. I was trying to put it in my __previewjs__ folder instead of the app root folder. This should work!

Thanks!

jordanarldt avatar Sep 14 '22 03:09 jordanarldt

@fwouts I think you should be able to close this issue since the alias functionality seems to work! 👍

jordanarldt avatar Sep 18 '22 05:09 jordanarldt

Awesome to hear!

I'll leave this open until I've written some docs mentioning this approach 😊

fwouts avatar Sep 18 '22 05:09 fwouts