storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.75k stars 9.33k forks source link

Be able to mock global functions, e.g. to mock React hooks dependencies #11227

Closed arthakdoo closed 5 months ago

arthakdoo commented 4 years ago

Is your feature request related to a problem? Please describe. We often cannot run a storybook around some component which uses React hooks to fetch some data, e.g. useQuery or useMutation from the Apollo library. It fails because there is no Provider, and Apollo provider is not that easy to set up. Even when set up, it needs to be mocked, which Apollo has some support for, but some other libs don't.

Describe the solution you'd like Not only for hooks, but also for some other component dependencies, it would be very convenient to have something like Jest has, to be able to mock a function globally, like e.g. https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options. Something like storybook.mock. I think this could be possible because we run a storybook process, just like jest does.

Describe alternatives you've considered When the data is coming from e.g. the useContext, it is fairly easy to circumvent, but it is still frustrating, because the only solution we currently see is to wrap each story into some fake Provider.

Are you able to assist bring the feature to reality? I have not had any contribution to Storybook so far, and I could find some time to try, but I am afraid this would be an advanced task.

Additional context -no screenshots-

tmeasday commented 4 years ago

Hi @dmaksimovic -- I think it is possible to do this with a custom webpack config that aliases the import (e.g. aliases react-apollo to your own mock version).

Having said that, I agree first class support for this in SB would be really cool. Do you have thoughts on an API for it?

tooppaaa commented 4 years ago

An option for this exact use case could be https://github.com/mswjs/msw. There has been experiment to add this to Storybook by @yannbf.

If i'm right, msw starts asynchronously but our stories are synced. I think your work @tmeasday on async stories will unlock the use of that tool and ensure same data for unit test / storybook usage.

Having a mock mechanism in storybook might sound too much, What do you think ?

arthakdoo commented 4 years ago

Hi @dmaksimovic -- I think it is possible to do this with a custom webpack config that aliases the import (e.g. aliases react-apollo to your own mock version).

Having said that, I agree first class support for this in SB would be really cool. Do you have thoughts on an API for it?

Im afraid i don't. I've only been consumer of storybook for 3 years in 2 different companies but i have zero knowledge on its source and architecture. This issue is basically an obstacle to our team for using storybook, as we more and more shift to hook based components, and i only imagine we're not the only one's, as Facebook is pushing everybody in this direction. Service workers and custom webpacks could be a strong argument for those who oppose using storybook as it would become an overkill.

tmeasday commented 4 years ago

@dmaksimovic I guess what I meant was how do you imagine using such a feature?

tim-mccurrach commented 4 years ago

@yannbf It's mentioned in a comment above that you have worked on adding msw to storybook. This sounds like a really great development. What is the status of this work? (an experiment that might be built on later? / one that will probably be discarded? / is already completed?).

It goes without saying, I don't mean any pressure in asking this. I'm just excited by the prospect, regardless of the status of the work.

Thanks :)

kentokage commented 3 years ago

Any updates on this? I would like for this functionality to be available as well. This is necessary for components that may be using modules to making async calls to the network.

shilman commented 3 years ago

We have an async story mechanism in place now: https://storybook.js.org/docs/react/writing-stories/loaders

Does this unblock any of @yannbf 's work on MSW?

tooppaaa commented 3 years ago

In my own Storybook instances, we have MSW setup successfully. The incredible MSW team has also written an example: https://github.com/mswjs/examples/tree/master/examples/with-storybook

yannbf commented 3 years ago

We have an async story mechanism in place now: https://storybook.js.org/docs/react/writing-stories/loaders

Does this unblock any of @yannbf 's work on MSW?

That's a good question.. @kettanaito what do you think? If I recall correctly, MSW needs to setup its service worker once before storybook is loaded. Not something on a story level, but actually a place that runs a code globally one time and before storybook is fully started.

I assume the story loaders might be good for the scenario of which you need to set a specific mock for that story specifically, something like this maybe:

import { server } from 'test/server';

export const Primary = (args) => <TodoItem {...args} />;
Primary.loaders = [
  async () => {
    server.use(
      rest.post('/checkout', async (req, res, ctx) => {
        return res(ctx.status(500), ctx.json({ message: testErrorMessage }));
      })
    );
  },
];

But I'm not sure if that works, it's something to experiment with for sure!

binishjoshi commented 5 months ago

Hi @dmaksimovic -- I think it is possible to do this with a custom webpack config that aliases the import (e.g. aliases react-apollo to your own mock version).

Having said that, I agree first class support for this in SB would be really cool. Do you have thoughts on an API for it?

Something like an interceptor would be cool. It would then intercept when some function is being called and return with mocked data.

yannbf commented 5 months ago

Hey everyone! We just released a module mocking functionality in Storybook 8.1, please give it a try! https://storybook.js.org/blog/type-safe-module-mocking/

shilman commented 5 months ago

Good shout out @yannbf. Closing this now -- I think our current mechanisms should be able to mock anything one would like!