Skip to content

test_runner: exclude mocked CJS modules from coverage#61723

Open
ThanhNguyxn wants to merge 1 commit intonodejs:mainfrom
ThanhNguyxn:fix-test-coverage-mocked-cjs-modules
Open

test_runner: exclude mocked CJS modules from coverage#61723
ThanhNguyxn wants to merge 1 commit intonodejs:mainfrom
ThanhNguyxn:fix-test-coverage-mocked-cjs-modules

Conversation

@ThanhNguyxn
Copy link

Summary

  • Fix coverage report incorrectly including mocked CJS modules when imported into ESM
  • Add regression test for CJS module mocking scenario

Description

When a CommonJS module is mocked and imported into an ESM module, the coverage report incorrectly includes the mocked module. This happens because V8 coverage reports use the original file URL without the mock search parameter (?node-test-mock=X) that the ESM loader adds.

Root Cause

PR #59348 fixed issue #59112 by checking if a coverage URL contains the kMockSearchParam query parameter to exclude mocked modules. However, this only works for ESM-to-ESM mocking because:

  1. The ESM loader's resolve hook adds the mock search param to the URL
  2. V8 coverage reports the URL with the search param for ESM modules
  3. But for CJS modules, V8 coverage reports the original file URL without the search param

Solution

In shouldSkipFileCoverage(), after checking the URL search params, also check if the base URL (without query params) is registered in the mocks registry with active: true.

Reproduction (from #61709)

// dependency.cjs
module.exports = { sum: (a, b) => a + b };

// subject.mjs  
import { sum } from './dependency.cjs';
export const theModuleSum = (a, b) => sum(a, b);

// test.mjs
import { mock } from 'node:test';
mock.module('./dependency.cjs', { namedExports: { sum: () => 42 } });
const { theModuleSum } = await import('./subject.mjs');
// dependency.cjs incorrectly appears in coverage report

Fixes: #61709

When a CommonJS module is mocked and imported into an ESM module,
the coverage report incorrectly includes the mocked module. This
happens because V8 coverage reports use the original file URL
without the mock search parameter that ESM loader adds.

This fix checks if the base URL (without query params) is registered
in the mocks registry in addition to checking the URL search params.

Fixes: nodejs#61709
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. labels Feb 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

node:test coverage attempts to cover mocked modules

3 participants