MockAdaptor in Bella OpenAPI: A Complete Testing Guide for AI Service Simulation

The MockAdaptor in Bella OpenAPI is a protocol adapter that returns deterministic, fabricated responses instead of calling real AI services, enabling isolated testing without network dependencies or API credentials.

The Bella OpenAPI project (lianjiatech/bella-openapi) provides a robust testing infrastructure through its MockAdaptor implementation. This Spring-managed component allows developers to simulate AI completion responses, control latency characteristics, and validate tool-call handling without connecting to external providers like OpenAI or Anthropic.

What Is the MockAdaptor in Bella OpenAPI?

The MockAdaptor is a specialized implementation of the protocol-adapter interfaces declared as a Spring component with the name "mock". Located at api/server/src/main/java/com/ke/bella/openapi/protocol/completion/MockAdaptor.java, it intercepts requests that specify the mock protocol and generates synthetic responses based on custom HTTP headers.

The AdaptorManager selects this implementation when a request includes the header X-BELLA-PROTOCOL: mock (or the equivalent protocol parameter). While the completion mock provides full functional simulation, the embedding and TTS variants—found at api/server/src/main/java/com/ke/bella/openapi/protocol/embedding/MockAdaptor.java and api/server/src/main/java/com/ke/bella/openapi/protocol/tts/MockAdaptor.java—currently throw BizParamCheckException as placeholder implementations.

Core Capabilities of the MockAdaptor

Deterministic Response Generation

The adaptor ensures that identical requests produce identical outputs, eliminating flakiness in automated test suites. It constructs a MockCompletionRequest object that parses incoming parameters and generates appropriate CompletionResponse payloads without performing network I/O.

Latency and Streaming Simulation

Through custom headers, the MockAdaptor mimics real-world network conditions. The X-BELLA-MOCK-TTFT header controls time-to-first-token (think time), X-BELLA-MOCK-TTLT sets total latency for the complete response, and X-BELLA-MOCK-INTERVAL specifies delays between SSE chunks during streaming.

Tool Call and Function Simulation

When the X-BELLA-MOCK-FUNCTION header is provided with a URL-encoded JSON payload, the adaptor injects synthetic tool-call objects into the response. This allows validation of function-calling logic and reasoning pipelines without invoking actual model APIs.

Implementing Tests with the MockAdaptor

Selecting the Mock Protocol

Activate the adaptor by setting the protocol header in your HTTP requests. The following example demonstrates a basic completion test with simulated latency characteristics:

mockMvc.perform(
        post("/v1/chat/completions")
            .header("X-BELLA-PROTOCOL", "mock")
            .header("X-BELLA-MOCK-TTFT", "200")
            .header("X-BELLA-MOCK-TTLT", "1500")
            .header("X-BELLA-MOCK-INTERVAL", "100")
            .content(jsonRequestBody)
            .contentType(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.choices[0].message.content").exists());

The headers are parsed in the MockCompletionRequest constructor (lines 54-68 of MockAdaptor.java), which configures the timing behavior for the synthetic response.

Testing Function Call Scenarios

To validate tool-handling logic, encode your desired function call as JSON and pass it via the function header:

String functionCall = URLEncoder.encode(
        "{\"name\":\"get_weather\",\"arguments\":{\"city\":\"London\"}}",
        StandardCharsets.UTF_8);

mockMvc.perform(
        post("/v1/chat/completions")
            .header("X-BELLA-PROTOCOL", "mock")
            .header("X-BELLA-MOCK-FUNCTION", functionCall)
            .content(jsonBody)
            .contentType(MediaType.APPLICATION_JSON))
    .andExpect(jsonPath("$.choices[0].message.tool_calls[0].function.name")
                .value("get_weather"));

This pattern creates a Message.ToolCall object (lines 102-112 in the source) within the response choices array, enabling end-to-end testing of function dispatching.

Validating Streaming Behavior

For Server-Sent Events (SSE) testing, invoke the streaming endpoint while specifying chunk intervals:

MvcResult result = mockMvc.perform(
        post("/v1/chat/completions/stream")
            .header("X-BELLA-PROTOCOL", "mock")
            .header("X-BELLA-MOCK-INTERVAL", "50")
            .content(jsonBody)
            .contentType(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andReturn();

String ssePayload = result.getResponse().getContentAsString();
assertTrue(ssePayload.split("\n").length > 3);

The streamCompletion method utilizes MockNetworkIO to emit a sequence of StreamCompletionResponse chunks generated by MockCompletionRequest#getChunks() (lines 221-244), respecting the specified timing parameters.

Direct Unit Testing

Bypass the HTTP layer by instantiating the adaptor directly for isolated component testing:

MockAdaptor mock = new MockAdaptor();
CompletionProperty prop = new CompletionProperty();
CompletionResponse resp = mock.completion(
        dummyRequest,
        "https://api.mock",  // URL ignored by implementation
        prop);

assertEquals("mock-model", resp.getModel());
assertNotNull(resp.getChoices().get(0).getMessage().getContent());

The completion method (lines 59-81) returns a fully populated CompletionResponse with synthetic content and metadata.

Summary

  • The MockAdaptor in Bella OpenAPI provides deterministic, fabricated responses for the completion protocol at api/server/src/main/java/com/ke/bella/openapi/protocol/completion/MockAdaptor.java.
  • It is activated via the X-BELLA-PROTOCOL: mock header and supports latency simulation through X-BELLA-MOCK-TTFT, X-BELLA-MOCK-TTLT, and X-BELLA-MOCK-INTERVAL headers.
  • Tool-call testing is supported via the X-BELLA-MOCK-FUNCTION header, which injects synthetic function calls into responses for validating reasoning pipelines.
  • Both synchronous completions and streaming SSE outputs can be tested without network access, API keys, or rate-limit concerns.
  • Embedding and TTS mocks exist as placeholder implementations at their respective protocol paths but throw BizParamCheckException when invoked.

Frequently Asked Questions

What HTTP headers does the MockAdaptor recognize?

The MockAdaptor processes several custom headers to control its behavior: X-BELLA-PROTOCOL (set to "mock" to select the adapter), X-BELLA-MOCK-TTFT for time-to-first-token simulation, X-BELLA-MOCK-TTLT for total latency, X-BELLA-MOCK-INTERVAL for SSE chunk delays, and X-BELLA-MOCK-FUNCTION for injecting tool calls. These headers are parsed in the MockCompletionRequest constructor within the main adaptor class.

Can I use the MockAdaptor for embedding or text-to-speech testing?

Currently, no. The embedding mock at api/server/src/main/java/com/ke/bella/openapi/protocol/embedding/MockAdaptor.java and the TTS mock at api/server/src/main/java/com/ke/bella/openapi/protocol/tts/MockAdaptor.java are placeholder implementations that throw BizParamCheckException when invoked. Only the completion protocol mock provides full functional simulation according to the source code.

How does the MockAdaptor simulate network latency?

The adaptor reads timing headers during request construction and applies delays through its internal MockNetworkIO logic before returning responses or emitting SSE chunks. This allows tests to verify timeout handling, loading states, and streaming UX under controlled conditions without actual network variability.

Is the MockAdaptor suitable for load testing?

Yes, because it eliminates external network calls and API rate limits, the MockAdaptor can handle high-throughput scenarios for stress-testing the Bella OpenAPI server infrastructure itself. However, it does not simulate backpressure or resource contention of real AI models, so it should complement rather than replace integration tests with actual providers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →