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:

Configure the Gen AI client python
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.

Start aimock shell
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:

Function calling fixture json
{
  "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:

Gemini response shape json
{
  "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:

conftest.py python
import pytest

# The aimock fixture is provided by aimock-pytest
# pip install aimock-pytest
test_adk_agent.py python
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:

.github/workflows/test.yml yaml
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.

Non-standard prefix example python
# 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",
    },
)