做 #4678 时发现,按第十条军规立案,unassigned。 ## 现象 `packages/client-react` 的 `package.json` 只有 `build` 和 `typecheck` 两个脚本,**没有 `test`**,`src/` 下也没有任何测试文件。它导出 8 个公开 hook: `useMetadataSubscription` / `useDataSubscription` / `useMetadataSubscriptionCallback` / `useDataSubscriptionCallback` / `useRealtimeConnection` / `useAutoRefresh`(以及 #4678 新增的 `useBulkDataSubscription` / `useBulkDataSubscriptionCallback`)。 这些 hook 的正确性完全没有运行时验证。typecheck 只能证明它们**类型对**,证明不了: - `useEffect` 的依赖数组对不对(漏一项 → 订阅不随 `object` 变化重建,换对象后还在收旧对象的事件); - 卸载时是否真的 `unsubscribe`(漏了 → 内存泄漏 + 幽灵回调); - `useAutoRefresh` 是否真的在事件到达时调了 `refetch`。 最后一条正是 #4678 修的那个 bug 的形状:**它对批量写不刷新,而这件事 typecheck 永远看不见**。同类缺陷可以再次静默溜进来。 ## 为什么没有顺手在 #4678 里补 全仓**没有任何 DOM 测试基座**: - 没有根 `vitest.config.ts` / `vitest.workspace.ts`; - 全仓 `package.json` 里 grep 不到 `jsdom`,也 grep 不到 `@testing-library/*`。 所以给 hook 写测试不是"加一个 `.test.tsx`",而是要引入 `jsdom` + `@testing-library/react`(或 `react-hooks` 等价物)两个新的 devDependency、配 vitest environment、并让它进 CI 的 `Test Core` 分片。这是个该由维护者定的取舍(新依赖 + CI 时长),不该作为一个 hook 修复的 rider 夹带进来。 ## 处置方向 1. 给 `client-react` 加 `test: vitest run` + 一份 `vitest.config.ts`(`environment: 'jsdom'`); 2. devDeps 加 `jsdom` + `@testing-library/react`; 3. 起步测试覆盖三件 typecheck 覆盖不到的事:**依赖数组导致的重订阅**、**卸载时退订**、**回调确实被调用**(`useAutoRefresh` 对逐记录和批量两条流都要断言); 4. 确认它被 CI 的 turbo `test` 任务捡到。 ## 参考 - #4678 / 其 PR —— 这次修的正是一个 typecheck 看不见的行为缺陷 - `packages/client-react/src/realtime-hooks.tsx` - `packages/client/src/realtime-api-data.test.ts` —— client 层已有的边界测试,可作断言风格参照
Activity
os-zhuang commentedon Aug 2, 2026
认领开工。
session_01LYnZrTwXbrctB8E8HpJAPTclaude/issue-4682-client-react-test-harness维护者已批准本 issue「处置方向」里那个取舍(新增
jsdom+@testing-library/react两个 devDependency,以及随之而来的 CI 时长)——这正是当初没在 #4678 里顺手补、而是单独立案的原因。#4678 已合并(#4683,commit
0884452),所以起步测试会连新增的useBulkDataSubscription/useBulkDataSubscriptionCallback一起覆盖,useAutoRefresh的断言按 issue 要求覆盖逐记录和批量两条流。Generated by Claude Code
test(client-react): give the package a test harness and pin realtime …
fix(client-react): stop five hooks from looping on dependency identity (