Problem
Static coverage reachability follows an import into a module that Vitest replaces with vi.mock().
The mocked module and its exports are therefore reported as test-covered even though the real module
is never executed by that test.
This also changes coverage-derived health severity when a wrapper test is added, which can make
stable health identities regress unexpectedly.
Minimal reproduction
// src/dependency.ts
export const renderDependency = (): string => "real dependency";
// src/wrapper.ts
import { renderDependency } from "./dependency";
export const renderWrapper = (): string => renderDependency();
// src/wrapper.test.ts
import { describe, expect, it, vi } from "vitest";
import { renderWrapper } from "./wrapper";
vi.mock("./dependency", () => ({
renderDependency: vi.fn<() => string>(() => "mocked dependency"),
}));
describe("renderWrapper", () => {
it("uses the mock", () => {
expect(renderWrapper()).toBe("mocked dependency");
});
});
With src/entry.ts as the package entry, run:
fallow health --coverage-gaps --format json --quiet --no-cache
Fallow 3.9.1 reports three runtime files, two covered files, and only src/entry.ts as untested.
The two covered files are src/wrapper.ts and src/dependency.ts.
Expected
The static coverage graph should treat the literal target of vi.mock("./dependency") as a mocked
edge for that test root. src/wrapper.ts is test-reachable, but src/dependency.ts is not covered
by this test.
The same likely applies to jest.mock() and vi.doMock() where the target is a static string.
Problem
Static coverage reachability follows an import into a module that Vitest replaces with
vi.mock().The mocked module and its exports are therefore reported as test-covered even though the real module
is never executed by that test.
This also changes coverage-derived health severity when a wrapper test is added, which can make
stable health identities regress unexpectedly.
Minimal reproduction
With
src/entry.tsas the package entry, run:Fallow 3.9.1 reports three runtime files, two covered files, and only
src/entry.tsas untested.The two covered files are
src/wrapper.tsandsrc/dependency.ts.Expected
The static coverage graph should treat the literal target of
vi.mock("./dependency")as a mockededge for that test root.
src/wrapper.tsis test-reachable, butsrc/dependency.tsis not coveredby this test.
The same likely applies to
jest.mock()andvi.doMock()where the target is a static string.