question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Create React App - Mocks work only every 2nd page reload

See original GitHub issue

Environment

Name Version
msw 0.20.5
browser Chrome 84.0.4147.125 (Official Build) (64-bit)
OS Kubuntu 20.04, 5.4.0-42-generic

Request handlers

`handlers.ts`, taken from the official tutorial + a simple get route

import { rest } from 'msw'
export const handlers = [
  rest.get('http://localhost:3001/test', (req, res,ctx) => {

    return res(ctx.json({key: "value"}));

  }),
  rest.post('/login', (req, res, ctx) => {
    // Persist user's authentication in the session
    sessionStorage.setItem('is-authenticated', "true")
    return res(
      // Respond with a 200 status code
      ctx.status(200),
    )
  }),
  rest.get('/user', (req, res, ctx) => {
    // Check if the user is authenticated in this session
    const isAuthenticated = sessionStorage.getItem('is-authenticated')
    if (!isAuthenticated) {
      // If not authenticated, respond with a 403 error
      return res(
        ctx.status(403),
        ctx.json({
          errorMessage: 'Not authorized',
        }),
      )
    }
    // If authenticated, return a mocked user details
    return res(
      ctx.status(200),
      ctx.json({
        username: 'admin',
      }),
    )
  }),
]

`browser.ts`, taken from the official tutorial

// src/mocks/browser.js
import { setupWorker } from 'msw'
import { handlers } from './handlers'
// This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...handlers)

Starting the worker, right above `React.render`

  if (process.env.NODE_ENV === "development") {
    const { worker } = require("./mocks/browser");
    console.log(worker);
    worker.start();
  }

  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  );

Request logic

  useEffect(() => {
    setTimeout(async () => {
      {
        const resp = await fetch("http://localhost:3001/test");
        console.log(await resp.text());
      }
    }, 1000);
  }, []);

Current behavior

Mocking works only every 2nd page refresh. I can keep mashing F5, and only every 2nd refresh comes the expected response (CTRL+F5, that is hard refresh, makes it work every time).

During the non-working refreshes:

  • If the request is made to the same origin as the webpack devserver, simply the page’s source is sent back (Example: fetch('/test') or fetch('http://localhost:3000/test'))
  • If we’re mocking under a different mask, such as fetch('http://localhost:3001/test'), this is sent back:
GET http://localhost:3001/test net::ERR_CONNECTION_REFUSED
App.tsx:12 Uncaught (in promise) TypeError: Failed to fetch

Moreover, attemping to load the service worker asynchronously makes the mock work only on the initial load (then you need to unregister the worker, and refresh the page to have it work again… for just one time).

(async () => {
    if (process.env.NODE_ENV === "development") {
      const { worker } = await import("./mocks/browser");
      console.log(worker);
      await worker.start();
    }

    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById("root")
    );

    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();
  })();

Expected behavior

Mocking works every refresh.

Repo link

Click

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
marcosvega91commented, Aug 29, 2020

Ho @Sun-2 thanks for raising this 😃.

The problem with your example is that the CRA will unregister MSW serviceWorker with this line of code serviceWorker.unregister(). To use MSW you should remove this line. Maybe we can add this into the documentation. What do you think @kettanaito ?

0reactions
marcosvega91commented, Aug 31, 2020

Yes we are also adding a note on the doc. Thank you 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot mock window.location in create-react-app using jest
I was first trying to set a testURL in jest config but from what I can see online, that this is not supported...
Read more >
How To Test a React App with Jest and React Testing Library
This code will set up and tear down the mock implementation so that each test starts from a level playing field. jest.spyOn(window, "fetch"); ......
Read more >
Thinking in React
The first thing you'll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all...
Read more >
Create React App
Create React App · Less to Learn. You don't need to learn and configure many build tools. Instant reloads help you focus on...
Read more >
How to Build a Custom Pagination Component in React
We often work with web applications that need to fetch large amounts of data from a server through APIs and render it on...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found