Testing Mock API
Usage for Anthropic/OpenAI mock APIs, runOneshot, and mock server types.
Testing Mock API
startMockAnthropicServer()
declare function startMockAnthropicServer(): Promise<MockServer>;type MockServer = {
port: number;
server: http.Server;
close: () => void;
requests: Array<{ model: string; messages: unknown[]; stream: boolean; timestamp: string }>;
onLog: (handler: (line: string) => void) => void;
};type MockLogEntry = {
ts: string;
type: "request" | "response" | "error" | "info";
method?: string;
url?: string;
model?: string;
stream?: boolean;
messageCount?: number;
userText?: string;
systemPromptLength?: number;
replyText?: string;
requestBody?: unknown;
error?: string;
message?: string;
};import { startMockAnthropicServer } from "@sna-sdk/testing";
const mock = await startMockAnthropicServer();
process.env.ANTHROPIC_BASE_URL = `http://localhost:${mock.port}`;
process.env.ANTHROPIC_API_KEY = "sk-test";
mock.onLog((line) => {
process.stdout.write(`${line}\n`);
});
try {
// Run code that expects an Anthropic-compatible API.
} finally {
mock.close();
}Behavior:
- Starts on an available port chosen by the OS. The current implementation does not accept a fixed port option.
- Provides an Anthropic-compatible
POST /v1/messagesendpoint. - Supports CORS preflight requests.
- Records parsed requests in
mock.requests. - Emits JSONL log lines through
mock.onLog. - For normal text, replies with the last user text reversed. This makes responses deterministic without looking realistic.
- If tools are declared and the latest user text contains
[tool:Name], returns or streams atool_useblock for that tool. - Supports streaming SSE and non-streaming JSON responses.
startMockOpenAIServer(options?)
declare function startMockOpenAIServer(options?: MockOpenAIOptions): Promise<MockOpenAIServer>;type MockOpenAIOptions = {
models?: Array<{ id: string; owned_by?: string }>;
responseText?: string | ((ctx: MockOpenAIResponseContext) => string);
chunkSize?: number;
};import { startMockOpenAIServer } from "@sna-sdk/testing";
const mock = await startMockOpenAIServer({
models: [{ id: "gpt-5.4", owned_by: "openai" }],
responseText: ({ endpoint, userText }) => `${endpoint}: ${userText}`,
});
try {
const res = await fetch(`${mock.url}/v1/responses`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: "Bearer sk-test" },
body: JSON.stringify({ model: "gpt-5.4", input: "hello" }),
});
console.log(await res.json());
console.log(mock.requests[0]);
} finally {
await mock.close();
}Behavior:
- Starts on an available local port and exposes
mock.url. - Provides
GET /v1/models,POST /v1/chat/completions, andPOST /v1/responses. - Records parsed requests, including authorization, model, stream flag, user text, system prompt length, and the raw request body.
- Emits JSONL log lines through
mock.onLog. - Supports non-streaming JSON and streaming SSE for chat completions and responses.
- By default, replies with the last user text reversed. Use
responseTextfor fixed or per-request output.
runOneshot(cliArgs?)
declare function runOneshot(cliArgs?: string[]): Promise<void>;Use this when a test should exercise Claude against the mock Anthropic API without starting the full interactive CLI harness.
runOneshot starts the mock server, points ANTHROPIC_BASE_URL at it, runs claude with the provided CLI arguments, captures stdout/stderr, and exits the process with Claude's exit code. It also uses .sna/mock-claude-oneshot as CLAUDE_CONFIG_DIR.
Written files:
| File | Contents |
|---|---|
.sna/mock-claude-stdout.log | Captured Claude stdout. |
.sna/mock-claude-stderr.log | Captured Claude stderr. |
.sna/mock-claude-oneshot/ | Temporary Claude config directory. |
Instance helpers
generateInstanceName()
Creates a unique test instance name. Use it to avoid log/config directory collisions in parallel tests.
getInstancesDir() / getInstanceDir(name)
Resolve the storage path used by the testing CLI. Prefer these helpers over hard-coded .sna/instances paths.
listInstances()
Returns test instance metadata stored on disk. Useful for debug UIs and cleanup scripts.
readInstanceMeta(name) / writeInstanceMeta(name, meta)
Read and write test instance metadata. Use them when extra state must be attached to an isolated CLI run.
removeInstance(name)
Removes an instance directory and its logs. Use it during test cleanup.