test: localize mock.module setup to fresh imports

This commit is contained in:
YeonGyu-Kim
2026-04-04 19:49:25 +09:00
parent 8b8559f39d
commit a4db240d47
9 changed files with 204 additions and 158 deletions
@@ -1,33 +1,52 @@
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test"
mock.module("../../shared/logger", () => ({
log: mock(() => {}),
}))
mock.module("../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: mock(() => null),
readProviderModelsCache: mock(() => null),
}))
mock.module("../../shared/model-error-classifier", () => ({
shouldRetryError: mock(() => true),
getNextFallback: mock((chain: Array<{ model: string }>, attempt: number) => chain[attempt]),
hasMoreFallbacks: mock((chain: Array<{ model: string }>, attempt: number) => attempt < chain.length),
selectFallbackProvider: mock((providers: string[]) => providers[0]),
}))
mock.module("../../shared/provider-model-id-transform", () => ({
transformModelForProvider: mock((_provider: string, model: string) => model),
}))
const sharedLogMock = mock(() => {})
const readConnectedProvidersCacheMock = mock(() => null)
const readProviderModelsCacheMock = mock(() => null)
const shouldRetryErrorMock = mock(() => true)
const getNextFallbackMock = mock((chain: Array<{ model: string }>, attempt: number) => chain[attempt])
const hasMoreFallbacksMock = mock((chain: Array<{ model: string }>, attempt: number) => attempt < chain.length)
const selectFallbackProviderMock = mock((providers: string[]) => providers[0])
const transformModelForProviderMock = mock((_provider: string, model: string) => model)
import type { BackgroundTask } from "./types"
import type { ConcurrencyManager } from "./concurrency"
import type { OpencodeClient, QueueItem } from "./constants"
const { tryFallbackRetry } = await import("./fallback-retry-handler")
const { shouldRetryError, selectFallbackProvider } = await import("../../shared/model-error-classifier")
const { readProviderModelsCache } = await import("../../shared")
mock.restore()
async function importFreshFallbackRetryHandlerModule() {
mock.module("../../shared/logger", () => ({
log: sharedLogMock,
}))
mock.module("../../shared/connected-providers-cache", () => ({
readConnectedProvidersCache: readConnectedProvidersCacheMock,
readProviderModelsCache: readProviderModelsCacheMock,
}))
mock.module("../../shared/model-error-classifier", () => ({
shouldRetryError: shouldRetryErrorMock,
getNextFallback: getNextFallbackMock,
hasMoreFallbacks: hasMoreFallbacksMock,
selectFallbackProvider: selectFallbackProviderMock,
}))
mock.module("../../shared/provider-model-id-transform", () => ({
transformModelForProvider: transformModelForProviderMock,
}))
const retryHandlerModule = await import(`./fallback-retry-handler?test=${Date.now()}-${Math.random()}`)
mock.restore()
return {
tryFallbackRetry: retryHandlerModule.tryFallbackRetry,
shouldRetryError: shouldRetryErrorMock,
selectFallbackProvider: selectFallbackProviderMock,
readProviderModelsCache: readProviderModelsCacheMock,
}
}
const { tryFallbackRetry, shouldRetryError, selectFallbackProvider, readProviderModelsCache } =
await importFreshFallbackRetryHandlerModule()
function createDeferredPromise(): {
promise: Promise<void>
+32 -24
View File
@@ -1,5 +1,4 @@
import { describe, it, expect, beforeEach, afterEach, afterAll, mock, spyOn } from "bun:test"
import { SkillMcpManager } from "./manager"
import type { SkillMcpClientInfo, SkillMcpServerContext } from "./types"
import type { ClaudeCodeMcpServer } from "../claude-code-mcp-loader/types"
@@ -8,41 +7,50 @@ const mockHttpConnect = mock(() => Promise.reject(new Error("Mocked HTTP connect
const mockHttpClose = mock(() => Promise.resolve())
let lastTransportInstance: { url?: URL; options?: { requestInit?: RequestInit } } = {}
mock.module("@modelcontextprotocol/sdk/client/streamableHttp.js", () => ({
StreamableHTTPClientTransport: class MockStreamableHTTPClientTransport {
constructor(public url: URL, public options?: { requestInit?: RequestInit }) {
lastTransportInstance = { url, options }
}
async start() {
await mockHttpConnect()
}
async close() {
await mockHttpClose()
}
},
}))
// Mock OAuth provider for OAuth integration tests
const mockTokens = mock(() => null as { accessToken: string } | null)
const mockLogin = mock(() => Promise.resolve({ accessToken: "test-token" }) as Promise<{ accessToken: string } | null>)
mock.module("../mcp-oauth/provider", () => ({
McpOAuthProvider: class MockMcpOAuthProvider {
tokens = mockTokens
login = mockLogin
constructor(_opts: unknown) {}
},
}))
async function importFreshManagerModule(): Promise<typeof import("./manager")> {
mock.module("@modelcontextprotocol/sdk/client/streamableHttp.js", () => ({
StreamableHTTPClientTransport: class MockStreamableHTTPClientTransport {
constructor(public url: URL, public options?: { requestInit?: RequestInit }) {
lastTransportInstance = { url, options }
}
async start() {
await mockHttpConnect()
}
async close() {
await mockHttpClose()
}
},
}))
mock.module("../mcp-oauth/provider", () => ({
McpOAuthProvider: class MockMcpOAuthProvider {
tokens = mockTokens
login = mockLogin
constructor(_opts: unknown) {}
},
}))
const module = await import(`./manager?test=${Date.now()}-${Math.random()}`)
mock.restore()
return module
}
afterAll(() => { mock.restore() })
describe("SkillMcpManager", () => {
let manager: SkillMcpManager
let manager: any
beforeEach(() => {
beforeEach(async () => {
const { SkillMcpManager } = await importFreshManagerModule()
manager = new SkillMcpManager()
mockHttpConnect.mockClear()
mockHttpClose.mockClear()
mockTokens.mockClear()
mockLogin.mockClear()
})
afterEach(async () => {