Skip to content

fix: should not load real implementation when module is mocked#934

Merged
fi3ework merged 8 commits intomainfrom
mock-side-effects
Feb 4, 2026
Merged

fix: should not load real implementation when module is mocked#934
fi3ework merged 8 commits intomainfrom
mock-side-effects

Conversation

@9aoy
Copy link
Copy Markdown
Collaborator

@9aoy 9aoy commented Feb 3, 2026

Summary

should not load real implementation when module is mocked.

  • Modified rs.mock() to check the module cache first and avoid loading modules unless necessary (e.g., for spy/mock options)
  • Updated module factory handling to set factories instead of directly modifying cache, ensuring consistent behavior
  • Enhanced webpack runtime protection to prevent mocked module factories from being overwritten during chunk loading

Related Links

fix: #745

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

Copilot AI review requested due to automatic review settings February 3, 2026 11:08
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @9aoy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the rstest framework where mocking a module would still inadvertently load its real implementation, causing unwanted side effects. The changes introduce a more robust module mocking mechanism that prevents the execution of original module factories when a mock is active, ensuring better test isolation and predictability. This is achieved through modifications to the MockRuntimeRspackPlugin and the core mockRuntimeCode.js, along with new test cases to verify the behavior.

Highlights

  • Preventing Side Effects on Mocked Modules: The core issue of real module implementations loading despite being mocked, leading to unintended side effects, has been resolved. The module loading mechanism now correctly identifies and bypasses original module factories when a mock is active.
  • Refined Module Loading for rs.mock: The rs.mock function has been enhanced to only load a module's original implementation if it's already present in the cache. If not, it saves the original factory without executing it, thereby preventing side effects from modules that haven't been loaded yet.
  • Updated rs.doMock and rs.doMockRequire Logic: The internal implementation of rs.doMock and rs.doMockRequire has been refactored. They now use a factory-based approach to register mocked modules with the module system and clear existing cache entries, ensuring that subsequent imports correctly use the mock.
  • New E2E Tests for Side Effects and Unmocking: Several new end-to-end tests have been added to thoroughly validate the fix. These tests specifically demonstrate that mocked modules do not execute their side effects and that rs.unmock correctly restores the original module behavior.
Changelog
  • e2e/mock/fixtures/unmock/a.ts
    • Added a new module for testing mocking capabilities.
  • e2e/mock/fixtures/unmock/noUnmock.test.ts
    • Added a test case to verify the mocking of a local module.
  • e2e/mock/fixtures/unmock/rstest.setup.ts
    • Added a mock setup for the newly introduced local module a.ts.
  • e2e/mock/fixtures/unmock/unmock.test.ts
    • Added a test case to verify the unmocking functionality for a local module.
  • e2e/mock/src/sideEffects.ts
    • Added a module that includes a side effect for specific testing scenarios.
  • e2e/mock/tests/sideEffects.test.ts
    • Added a test case to ensure that side effects are not executed when a module is mocked.
  • packages/core/src/core/plugins/mockRuntime.ts
    • Modified the module loading logic to prevent original module factories from being loaded if a mock is present, by checking rstest_original_module_factories.
  • packages/core/src/core/plugins/mockRuntimeCode.js
    • Updated rs.mock to conditionally load original modules only if they are already in the cache, preventing unintended side effects.
    • Enhanced rs.mock to explicitly load original modules for spy or mock options if they haven't been loaded yet, ensuring these features work correctly.
    • Refactored rs.doMock and rs.doMockRequire to use a factory-based approach, ensuring mocks are correctly registered and module caches are cleared to force the use of the mock.
Activity
  • The pull request was created to address and fix an issue where real module implementations were loaded even when mocked, as detailed in web-infra-dev/rstest/issues/745.
  • The author, 9aoy, has implemented changes across several core mocking logic files and introduced new end-to-end tests to validate the fix.
  • The checklist indicates that tests have been updated (or not required) and documentation has been updated (or not required), suggesting the author has considered these aspects.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses the issue of preventing real module implementations from loading when a module is mocked, which is crucial for isolating tests and avoiding unintended side effects. The changes involve modifying how rs.mock and rs.doMock interact with Webpack's module loading mechanism, primarily by prioritizing the mocked module factory and delaying the loading of the original module until explicitly required for features like spying. New test cases have been added to validate this behavior, including scenarios with side effects and unmocking.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical issue where rs.mock() was loading the real module implementation before applying the mock, causing unwanted side effects to execute.

Changes:

  • Modified rs.mock() to check the module cache first and avoid loading modules unless necessary (e.g., for spy/mock options)
  • Updated module factory handling to set factories instead of directly modifying cache, ensuring consistent behavior
  • Enhanced webpack runtime protection to prevent mocked module factories from being overwritten during chunk loading

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/core/src/core/plugins/mockRuntimeCode.js Refactored rs.mock() to check cache before loading modules, preventing side effects. Updated rs.doMock() to use module factories consistently.
packages/core/src/core/plugins/mockRuntime.ts Added checks for rstest_original_module_factories to prevent webpack from overwriting mocked modules during chunk loading.
e2e/mock/tests/sideEffects.test.ts New test verifying that side effects don't execute when a module is mocked.
e2e/mock/src/sideEffects.ts Test fixture module with side effects.
e2e/mock/fixtures/unmock/unmock.test.ts Enhanced test to verify unmock functionality with custom modules.
e2e/mock/fixtures/unmock/rstest.setup.ts Added mock setup for custom module to test unmock behavior.
e2e/mock/fixtures/unmock/noUnmock.test.ts Test to verify mocked state persists without unmock.
e2e/mock/fixtures/unmock/a.ts Simple test fixture module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 3, 2026

📝 Rstest Ecosystem CI: Open

suite result
rslib ✅ success
modernjs ❌ failure
rsdoctor ✅ success
rspress ✅ success
rsbuild ✅ success

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 4, 2026

📝 Rstest Ecosystem CI: Open

suite result
rslib ✅ success
modernjs ✅ success
rspress ✅ success
rsdoctor ✅ success
rsbuild ✅ success

@9aoy 9aoy requested a review from fi3ework February 4, 2026 08:17
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 4, 2026

📝 Rstest Ecosystem CI: Open

suite result
rsbuild ✅ success
modernjs ✅ success
rslib ✅ success
rspress ✅ success
rsdoctor ✅ success

@fi3ework
Copy link
Copy Markdown
Member

fi3ework commented Feb 4, 2026

👍🏻

@fi3ework fi3ework merged commit 38215b8 into main Feb 4, 2026
15 of 17 checks passed
@fi3ework fi3ework deleted the mock-side-effects branch February 4, 2026 08:47
@9aoy 9aoy mentioned this pull request Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: rs.mock() loads real implementation (executing side effects)

3 participants