Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browser mode: cannot overwrite request handler when MSW is initialized in setup file #6690

Closed
6 tasks done
foxaltus opened this issue Oct 11, 2024 · 2 comments · Fixed by #6759
Closed
6 tasks done
Labels
feat: browser Issues and PRs related to the browser runner p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@foxaltus
Copy link

foxaltus commented Oct 11, 2024

Describe the bug

I have a HelloWorld.tsx component that displays a random joke using the https://api.chucknorris.io/jokes/random API (sorry about that), which I'm mocking using MSW:

// src/mocks/handlers.ts
import { http, HttpResponse } from "msw";

export const handlers = [
  http.get("https://api.chucknorris.io/jokes/random", () => {
    return HttpResponse.json({
      icon_url: "https://api.chucknorris.io/img/avatar/chuck-norris.png",
      id: "hbCl1mPLQHuKuZGij--jZA",
      url: "https://api.chucknorris.io/jokes/hbCl1mPLQHuKuZGij--jZA",
      value: "Chuck Norris can win connect four in three move",
    });
  }),
];

using the MSW worker:

// src/mock/browser.ts
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";

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

MSW is initialized in vitest-setup.ts:

import { cleanup } from "@testing-library/react";
import { worker } from "./mocks/browser";

// from https://mswjs.io/docs/getting-started/integrate/node#setup
// Establish API mocking before all tests.
beforeAll(async () => {
  await worker.start({ onUnhandledRequest: "error" });
});

// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => {
  worker.resetHandlers();
  cleanup();
});

// Clean up after the tests are finished.
afterAll(() => {
  worker.stop();
});

🐛 When I run the tests, the test cases that use default handlers pass, but the ones that override them fail, eg:

// HelloWorld.test.tsx

// PASS
test("tells a joke", async () => {
  const { findByText } = render(<HelloWorld name="Chuck" />);
  const element = await findByText(/Chuck Norris can win connect four/);
  expect(element).toBeInTheDocument();
});

// FAIL
test("tells another joke", async () => {
  worker.use(
    http.get("https://api.chucknorris.io/jokes/random", () =>
      HttpResponse.json({
        icon_url: "https://api.chucknorris.io/img/avatar/chuck-norris.png",
        id: "ihYDJ5NcT4mgj1vN5taKVQ",
        url: "https://api.chucknorris.io/jokes/ihYDJ5NcT4mgj1vN5taKVQ",
        value: "Chuck Norris can milk a bucket with a cow.",
      })
    )
  );
  const { findByText } = render(<HelloWorld name="Chuck" />);
  const element = await findByText(/Chuck Norris can milk a bucket/);
  expect(element).toBeInTheDocument();
});

The text from the response is not found (the one from the default mock is here though), which seems to indicate that the override is not working.

However, if I move the initialization from the setup file to the test file itself, then all tests pass 🤔

Refs:

Reproduction

The issue can be reproduced at https://github.com/foxaltus/vitest-browser-mode-msw.
The workaround can be seen here: https://github.com/foxaltus/vitest-browser-mode-msw/compare/workaround

Use pnpm run test script.

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
    Memory: 8.42 GB / 31.73 GB
  Binaries:
    Node: 18.20.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.5.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.9.0 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (129.0.2792.79)
    Internet Explorer: 11.0.26100.1882
  npmPackages:
    @vitejs/plugin-react: ^4.3.1 => 4.3.1 
    @vitest/browser: ^2.1.1 => 2.1.1
    @vitest/coverage-v8: ^2.1.1 => 2.1.1
    vite: ^5.4.8 => 5.4.8
    vitest: ^2.1.1 => 2.1.1

Used Package Manager

pnpm

Validations

@sheremet-va sheremet-va added feat: browser Issues and PRs related to the browser runner p3-minor-bug An edge case that only affects very specific usage (priority) and removed pending triage labels Oct 16, 2024
@sheremet-va sheremet-va moved this to Approved in Team Board Oct 16, 2024
@nstepien
Copy link
Contributor

I'm having the same issue in our codebase.

I discovered that worker.use() works fine in beforeAll/beforeEach/afterEach/afterAll.
It's also not just overwrites, setting up a new mock with worker.use() in tests will not work either.
These might be useful clues.

@sheremet-va
Copy link
Member

Thank you for the report. I found the issue. The worker file is imported twice - with a v= query inside the setup file and without a query in a test file. This is a bug in Vitest.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feat: browser Issues and PRs related to the browser runner p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants