Google ADK
Test your Google ADK agents without Gemini API keys. aimock speaks the Gemini API format
natively — generateContent, streamGenerateContent, and
function calling.
Quick Start
Point the Google Gen AI SDK at your aimock instance. ADK uses the Gen AI SDK under the hood, so this is all you need:
from google import genai
client = genai.Client(
vertexai=False,
api_key="test",
http_options={"api_version": "v1beta", "base_url": "http://localhost:4010"},
)
Start aimock with a Gemini-format fixture, then run your ADK agent. Requests to
generateContent and streamGenerateContent are handled
automatically.
npx aimock --fixtures fixtures/examples/adk/gemini-agent.json
Gemini API Format
aimock handles the Gemini native request and response format. ADK agents hit these endpoints:
| Method | Path | Format |
|---|---|---|
| POST | /v1beta/models/{model}:generateContent |
JSON |
| POST | /v1beta/models/{model}:streamGenerateContent |
JSON stream / SSE (with ?alt=sse) |
| WS | /ws/google.ai.generativelanguage.* |
Gemini Live WebSocket |
Gemini uses contents with parts rather than OpenAI's
messages array. aimock translates Gemini requests to the unified fixture
format internally, so the same match.userMessage works regardless of which
provider endpoint the request arrives on.
Function Calling
ADK agents rely heavily on Gemini function calling. The Gemini format uses
functionCall and functionResponse parts instead of the
OpenAI-style tool_calls array. aimock generates the correct Gemini response
shape from the same fixture format:
{
"fixtures": [
{
"match": { "userMessage": "weather" },
"response": {
"toolCalls": [
{
"name": "get_weather",
"arguments": "{\"city\":\"San Francisco\",\"unit\":\"fahrenheit\"}"
}
]
}
}
]
}
When a Gemini endpoint receives this fixture, aimock returns it as a
functionCall part:
{
"candidates": [{
"content": {
"role": "model",
"parts": [{
"functionCall": {
"id": "call_abc123",
"name": "get_weather",
"args": { "city": "San Francisco", "unit": "fahrenheit" }
}
}]
}
}]
}
With aimock-pytest
The aimock-pytest plugin provides a aimock fixture that starts
and stops the server automatically:
import pytest
# The aimock fixture is provided by aimock-pytest
# pip install aimock-pytest
from google import genai
def test_agent_weather_tool(aimock):
"""Test that ADK agent calls get_weather tool."""
aimock.load_fixtures("fixtures/examples/adk/gemini-agent.json")
client = genai.Client(
vertexai=False,
api_key="test",
http_options={"api_version": "v1beta", "base_url": aimock.url},
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="what is the weather in San Francisco?",
)
# Verify the tool call was returned
part = response.candidates[0].content.parts[0]
assert part.function_call.name == "get_weather"
CI with GitHub Action
Use the aimock GitHub Action to run aimock as a service in CI:
steps:
- uses: actions/checkout@v4
- name: Start aimock
uses: CopilotKit/aimock@v1
with:
fixtures: fixtures/examples/adk/gemini-agent.json
- name: Run ADK tests
run: pytest tests/
No real Gemini API keys needed in CI — aimock does not validate them. Note that ADK
/ the Google Gen AI SDK does not support a base_url environment variable
override, so you must configure the base URL programmatically in your test code using
http_options (see the pytest example above).
Arbitrary Path Prefixes
If your ADK configuration or a proxy layer adds a non-standard base URL prefix (e.g.
/my-app/v1beta/models/...), aimock normalizes it automatically. The
normalizeCompatPath feature strips arbitrary prefixes and rewrites paths
ending in known suffixes to their canonical form.
This means your ADK agent can use any base URL structure and aimock will still route the request correctly to the Gemini handler.
# Even with a custom prefix, aimock routes correctly
client = genai.Client(
vertexai=False,
api_key="test",
http_options={
"api_version": "v1beta",
"base_url": "http://localhost:4010/my-proxy",
},
)