mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
16.02k stars 526 forks source link

Mock APIs only work on the first load, after reloading the connection is refused #919

Closed Dani-Boy92 closed 3 years ago

Dani-Boy92 commented 3 years ago

Hello,

I am new to MSW and have the problem that msw returns the correct mock APIs after the first load, but after a reload / hotreload, e.g. due to a change in the code, it does not work anymore and the connection fails.

I am working with Storybook and RTK Query (but also tried it with different REST libraries).

storybook/preview.js

export const decorators = [
  (Story) => (
    <Provider store={store}>
      <Story />
    </Provider>
  ),
];
// get the mocked handlers (endpoints) and starts the service worker
if (typeof global.process === "undefined") {
  const { worker } = require("../src/browser");
  worker.start();
}

.../src/browser.js

import { setupWorker } from "msw";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);

.../src/handlers.js

import { rest } from "msw";

export const handlers = [
  rest.get("http://localhost:8000/api/v1/tours/:id", (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json({
        id: 1,
        title: "Free Female Guided Walking Tours thorugh lovely Kampala",
      })
    );
  }),
];

component with mocked API request

function SingleTourConnected(props) {

  const { data, isLoading, error } = useGetTourByIdQuery({ tourId: 1 });

  return (
    <SingleTourPure 
      title={data?.title}
      isLoading={isLoading}
      error={error}
    />
  );
}

Environment

kettanaito commented 3 years ago

Hey, @Dani-Boy92.

If you're using our storybook add-on, please don't skip it's initialization step:

// ./storybook/preview.js
import { addDecorator } from '@storybook/react';
import { initializeWorker, mswDecorator } from 'msw-storybook-addon';

initializeWorker();
addDecorator(mswDecorator);

Installation

This way you don't need to call worker.start() manually next to your story, which subjects it to a race condition, resulting in all sorts of unpredictable behavior.

export const decorators = [
  (Story) => (
    <Provider store={store}>
      <Story />
    </Provider>
  ),
];
-// get the mocked handlers (endpoints) and starts the service worker
-if (typeof global.process === "undefined") {
-  const { worker } = require("../src/browser");
-  worker.start();
-}

Could you please follow this suggestion and let me know if the issue is fixed?

kettanaito commented 3 years ago

Please use our Storybook add-on I've mentioned above. If it still doesn't work after you've followed the getting started instructions from its documentation, please open an issue in its repository. Thanks.