Skip to content

Commit 0368bc1

Browse files
committed
🧪 navigation_handle: 用 resetAttachedForTest 替代 vi.resetModules
vi.resetModules() 会清空全局模块缓存,导致后续测试重新加载 LoggerCore、 chrome mock 等模块时出错,在 CI 上表现为偶发失败。 改为导出 resetAttachedForTest() 重置模块级 attached 单例, 测试无需动态 import 即可验证多次调用的幂等性。
1 parent 9f42b5b commit 0368bc1

2 files changed

Lines changed: 10 additions & 20 deletions

File tree

src/app/service/content/gm_api/navigation_handle.test.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2-
import { UrlChangeEvent } from "./navigation_handle.js";
3-
4-
// attachNavigateHandler 使用模块级 attached 单例,需要在每个测试前重置模块
5-
const importFresh = async () => {
6-
vi.resetModules();
7-
// vi.resetModules() 会清空模块缓存,后续 import 得到全新的 LoggerCore 类,
8-
// 需要重新初始化以免后续测试文件中 LoggerCore.getInstance() 返回 undefined
9-
// @ts-expect-error 动态 import 路径别名在 tsc nodenext 下无法解析
10-
const { default: LC, EmptyWriter: EW } = await import("@App/app/logger/core");
11-
new LC({ level: "trace", consoleLevel: "trace", writer: new EW(), labels: { env: "test" } });
12-
return await import("./navigation_handle.js");
13-
};
2+
import { UrlChangeEvent, attachNavigateHandler, resetAttachedForTest } from "./navigation_handle";
143

154
describe("UrlChangeEvent", () => {
165
it.concurrent("应包含 url 属性", () => {
@@ -64,10 +53,10 @@ describe("attachNavigateHandler", () => {
6453

6554
beforeEach(() => {
6655
vi.restoreAllMocks();
56+
resetAttachedForTest();
6757
});
6858

69-
it("不支持 Navigation API 时不应注册监听器", async () => {
70-
const { attachNavigateHandler } = await importFresh();
59+
it("不支持 Navigation API 时不应注册监听器", () => {
7160
const win = { location: { href: "https://example.com/" } } as any;
7261
attachNavigateHandler(win);
7362
// 没有 navigation 属性,不应报错也不应标记为 attached
@@ -77,16 +66,14 @@ describe("attachNavigateHandler", () => {
7766
expect(mock.win.navigation.addEventListener).toHaveBeenCalledWith("navigate", expect.any(Function), false);
7867
});
7968

80-
it("应在 win.navigation 上注册 navigate 监听器", async () => {
81-
const { attachNavigateHandler } = await importFresh();
69+
it("应在 win.navigation 上注册 navigate 监听器", () => {
8270
const mock = createMockWin();
8371
attachNavigateHandler(mock.win);
8472
expect(mock.win.navigation.addEventListener).toHaveBeenCalledTimes(1);
8573
expect(mock.win.navigation.addEventListener).toHaveBeenCalledWith("navigate", expect.any(Function), false);
8674
});
8775

88-
it("多次调用只注册一次", async () => {
89-
const { attachNavigateHandler } = await importFresh();
76+
it("多次调用只注册一次", () => {
9077
const mock = createMockWin();
9178
attachNavigateHandler(mock.win);
9279
attachNavigateHandler(mock.win);
@@ -95,7 +82,6 @@ describe("attachNavigateHandler", () => {
9582
});
9683

9784
it("URL 变化时应派发 urlchange 事件", async () => {
98-
const { attachNavigateHandler } = await importFresh();
9985
const mock = createMockWin("https://example.com/");
10086
attachNavigateHandler(mock.win);
10187
mock.fireNavigate("https://example.com/new");
@@ -109,7 +95,6 @@ describe("attachNavigateHandler", () => {
10995
});
11096

11197
it("URL 未变化时不应派发事件", async () => {
112-
const { attachNavigateHandler } = await importFresh();
11398
const mock = createMockWin("https://example.com/");
11499
attachNavigateHandler(mock.win);
115100
// destination.url 与当前 href 相同

src/app/service/content/gm_api/navigation_handle.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ export class UrlChangeEvent extends Event {
1010

1111
let attached = false;
1212

13+
// 仅供测试使用,重置 attached 标记
14+
export const resetAttachedForTest = () => {
15+
attached = false;
16+
};
17+
1318
const getPropGetter = <T>(obj: T, key: keyof T) => {
1419
// 避免直接 obj[key] 读取。或会被 hack
1520
for (let t = obj; t; t = Native.objectGetPrototypeOf(t)) {

0 commit comments

Comments
 (0)