Server Action Mocking in Storybook?
Unanswered
American black bear posted this in #help-forum
American black bearOP
I am using storybook to build components in an isolated environment.
While building a newsletter form storybook crashed because I am handling form submission using a next.js server action. I understand that storybook cannot run server code and that these actions should be mocked, but so far I have failed to implement it using [storybook docs](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules).
If you guys can help me with any of the following I would appreciate it:
- Mocking server actions in storybook
- Storybook alternatives that "support" server code (maybe some library that injects a route into next.js
- Storybook alternatives that make this easier to implement
## What I've tried:
I've followed the storybook guide from the docs thoroughly:
1. Created
2. Added subpath imports to my
3. Added the mocked module to story configuration [like here](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules#using-mocked-modules-in-stories)
This results in webpack not being able to start storybook build
While building a newsletter form storybook crashed because I am handling form submission using a next.js server action. I understand that storybook cannot run server code and that these actions should be mocked, but so far I have failed to implement it using [storybook docs](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules).
If you guys can help me with any of the following I would appreciate it:
- Mocking server actions in storybook
- Storybook alternatives that "support" server code (maybe some library that injects a route into next.js
/app/[[...preview]]
if that exists)- Storybook alternatives that make this easier to implement
## What I've tried:
I've followed the storybook guide from the docs thoroughly:
1. Created
actions.mock.ts
that exports my original server action using the fn
utility from @storybook/test
[like here](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules#mock-files)2. Added subpath imports to my
package.json
[like here](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules#subpath-imports)3. Added the mocked module to story configuration [like here](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules#using-mocked-modules-in-stories)
This results in webpack not being able to start storybook build
pnpm run storybook
and an error in the console:Module build failed: UnhandledSchemeError: Reading from "node:url" is not handled by plugins (Unhandled scheme).
6 Replies
American black bearOP
bump
American black bearOP
bump
American black bearOP
please someone help 🥲
American black bearOP
bump
American black bearOP
Here is what I've got till now. I've pinpointed the problem to my db client being used, so I've tried to mock that too, but with no luck.
My db client logic is as follows:
My db client logic is as follows:
// ~/lib/cms/client.ts
import config from "@payload-config";
import { getPayload } from "payload";
export async function getPayloadClient() {
return getPayload({ config });
}
// ~/lib/cms/client.mock.ts
import { fn } from "@storybook/test";
import * as actual from "./client";
export * from "./client";
export const getPayloadClient = fn(actual.getPayloadClient).mockName(
"getPayloadClient",
);
And I use it in my server action for creating a newsletter subscription as follows:
// ~/app/actions/actions.ts
"use server"
import { errorResponse, successResponse } from "~/lib/utils/api";
import { newsletterSubscriptionSchema } from "~/lib/zod/newsletter";
import { getPayloadClient } from "#src/lib/cms/client";
import { type Newsletter } from "~/payload-types";
export async function createNewsletterSubscription(
email: string,
newsletters: (Newsletter | number)[] | null | undefined,
) {
try {
const parsedData = newsletterSubscriptionSchema.parse({
email,
newsletters,
});
// IMPORTANT: commenting out this line fixes storybook server, despite importing the mocked version
const payload = await getPayloadClient();
const data = await payload.create({
collection: "subscribers",
data: {
email: parsedData.email,
subscribedTo: parsedData.newsletters,
},
});
if (!data) {
throw new Error("Failed to create subscription");
}
return successResponse(data);
} catch (error) {
console.error("Error in subscription:", error);
return errorResponse(error);
}
}
// ~/app/actions/actions.mock.ts
import { fn } from "@storybook/test";
import * as actual from "./actions";
export * from "./actions";
export const createNewsletterSubscription = fn(
actual.createNewsletterSubscription,
).mockName("createNewsletterSubscription");