0Pricing
AI Agents · Lektion

LLM-Aufrufe in Tests mocken

unittest.mock, pytest-Fixtures sowie das Aufzeichnen und Wiedergeben von LLM-Responses.

LLM-Aufrufe in Tests mocken ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was ist Mocking?

Beim Mocking wird eine echte Funktion oder ein echtes Objekt durch eine simulierte Version ersetzt, die kontrollierte Antworten zurückgibt. Beim Testen von Agenten mocken wir LLM-API-Aufrufe, damit Tests sofort ausgeführt werden, nichts kosten und vorhersehbare Ergebnisse liefern.

Das Python-Modul unittest.mock ist dafür das Standardwerkzeug.

Grundlagen von unittest.mock.patch()

unittest.mock.patch(target) ersetzt das benannte Objekt vorübergehend für die Dauer eines Tests. Bei target handelt es sich um einen durch Punkte getrennten String, der auf das Objekt so verweist, wie es in dem zu testenden Modul importiert wird.

from unittest.mock import patch, MagicMock

# The function under test calls openai.chat.completions.create
# We patch it so no real API call is made

def ask_llm(question: str) -> str:
    import openai
    client = openai.OpenAI(api_key='test')
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': question}]
    )
    return resp.choices[0].message.content

with patch('openai.OpenAI') as mock_client_class:
    mock_instance = MagicMock()
    mock_client_class.return_value = mock_instance
    mock_instance.chat.completions.create.return_value = MagicMock(
        choices=[MagicMock(message=MagicMock(content='Paris'))]
    )
    result = ask_llm('Capital of France?')
    print(result)  # 'Paris' — no API call made

patch als Decorator in pytest verwenden

Bei der Verwendung als Decorator mit pytest fügt @patch() den Mock als Funktionsparameter ein. Der Mock wird nach Abschluss des Tests automatisch entfernt.

from unittest.mock import patch, MagicMock
import pytest

# Assume agent.py contains: import openai; client = openai.OpenAI(...)

@patch('agent.openai.OpenAI')
def test_agent_calls_llm(mock_openai_class):
    # Set up the mock chain
    mock_client = MagicMock()
    mock_openai_class.return_value = mock_client
    mock_client.chat.completions.create.return_value = MagicMock(
        choices=[MagicMock(message=MagicMock(content='Paris is the capital of France.'))]
    )

    from agent import ask_llm
    result = ask_llm('What is the capital of France?')

    assert 'Paris' in result
    mock_client.chat.completions.create.assert_called_once()

Eine wiederverwendbare Mock-Antwort erstellen

Mock-Antwortobjekte manuell zu erstellen, ist aufwendig. Erstellen Sie eine Hilfsfunktion, die korrekt strukturierte Mock-Objekte erzeugt, deren Form der Antwortstruktur des OpenAI SDK entspricht.

from unittest.mock import MagicMock

def make_mock_response(content: str, tool_calls: list = None) -> MagicMock:
    message = MagicMock()
    message.content = content
    message.tool_calls = tool_calls or []

    choice = MagicMock()
    choice.message = message
    choice.finish_reason = 'stop' if not tool_calls else 'tool_calls'

    response = MagicMock()
    response.choices = [choice]
    response.usage = MagicMock(total_tokens=42)
    return response

# Usage in tests:
# mock_create.return_value = make_mock_response('Hello!')
# mock_create.return_value = make_mock_response('', tool_calls=[...])

# --- demo ---
response = make_mock_response('The weather in Paris is 18C and sunny.')
print('content:', response.choices[0].message.content)
print('finish_reason:', response.choices[0].finish_reason)
print('total_tokens:', response.usage.total_tokens)

Tool-Aufrufe in Antworten mocken

Beim Testen der Tool-Aufruflogik eines Agenten muss die Mock-Antwort ein korrekt strukturiertes Feld tool_calls enthalten, damit der Parsing-Code des Agenten es richtig verarbeiten kann.

import json
from unittest.mock import MagicMock

def make_tool_call_response(tool_name: str, arguments: dict) -> MagicMock:
    tool_call = MagicMock()
    tool_call.id = 'call_abc123'
    tool_call.type = 'function'
    tool_call.function = MagicMock()
    tool_call.function.name = tool_name
    tool_call.function.arguments = json.dumps(arguments)

    message = MagicMock()
    message.content = None
    message.tool_calls = [tool_call]

    response = MagicMock()
    response.choices = [MagicMock(message=message, finish_reason='tool_calls')]
    return response

# mock.return_value = make_tool_call_response('search_web', {'query': 'Python tutorials'})

# --- demo ---
response = make_tool_call_response('search_web', {'query': 'Python tutorials'})
call = response.choices[0].message.tool_calls[0]
print('tool name:', call.function.name)
print('tool arguments:', call.function.arguments)
print('finish_reason:', response.choices[0].finish_reason)

pytest-Fixtures für Mocking

Mit pytest-Fixtures können Sie wiederverwendbaren Setup-Code definieren. Erstellen Sie eine Fixture, die den LLM-Client patcht und ihn jedem Test zur Verfügung stellt, der ihn anfordert – ganz ohne Wiederholungen.

import pytest
from unittest.mock import patch, MagicMock

@pytest.fixture
def mock_openai(make_mock_response):
    with patch('myagent.client.chat.completions.create') as mock_create:
        mock_create.return_value = MagicMock(
            choices=[MagicMock(message=MagicMock(
                content='Default mocked response',
                tool_calls=[]
            ))]
        )
        yield mock_create

# Now any test can use it:
def test_agent_responds(mock_openai):
    from myagent import agent
    result = agent.run('Hello')
    assert result is not None
    mock_openai.assert_called_once()

Die mocker-Fixture von pytest-mock

pytest-mock stellt eine mocker-Fixture bereit, die das Patchen vereinfacht. Sie räumt Mocks automatisch auf und bietet eine übersichtlichere Syntax als das direkte Verwenden von unittest.mock.patch.

# pip install pytest-mock

# In your test file:
def test_agent_with_mocker(mocker):
    mock_create = mocker.patch('myagent.client.chat.completions.create')
    mock_create.return_value = mocker.MagicMock(
        choices=[mocker.MagicMock(message=mocker.MagicMock(
            content='Mocked answer',
            tool_calls=[]
        ))]
    )

    from myagent import agent
    result = agent.run('What is 2+2?')
    assert 'answer' in result.lower() or '4' in result

    mock_create.assert_called_once()
    # No cleanup needed — mocker handles it

Aufzeichnen und Wiedergeben mit vcr.py

vcrpy zeichnet echte HTTP-Interaktionen beim ersten Durchlauf in einer „Kassetten“-Datei auf und gibt sie bei späteren Durchläufen wieder. Das eignet sich ideal zum Testen von Code, der die rohe HTTP-API statt eines SDK verwendet.

# pip install vcrpy
import vcr
import httpx

@vcr.use_cassette('fixtures/cassettes/openai_chat.yaml')
def test_with_recorded_response():
    # First run: makes a real HTTP call and records it
    # Subsequent runs: uses the recorded cassette (no network, no cost)
    response = httpx.post(
        'https://api.openai.com/v1/chat/completions',
        json={'model': 'gpt-4o-mini', 'messages': [{'role': 'user', 'content': 'Hello'}]},
        headers={'Authorization': 'Bearer YOUR_KEY'}
    )
    data = response.json()
    assert data['choices'][0]['message']['content'] is not None

Prüfen, ob der Mock korrekt aufgerufen wurde

Überprüfen Sie nach einem Test, ob der Mock mit den richtigen Argumenten aufgerufen wurde. So erkennen Sie Fehler, bei denen der Agent das falsche Modell oder fehlende Parameter sendet oder falsche Nachrichten übermittelt.

from unittest.mock import patch, MagicMock, call

@patch('myagent.client.chat.completions.create')
def test_agent_sends_correct_model(mock_create):
    mock_create.return_value = MagicMock(
        choices=[MagicMock(message=MagicMock(content='ok', tool_calls=[]))]
    )

    from myagent import agent
    agent.run('Hello')

    # Verify the mock was called with correct arguments
    mock_create.assert_called_once()
    call_kwargs = mock_create.call_args.kwargs
    assert call_kwargs['model'] == 'gpt-4o-mini'
    assert len(call_kwargs['messages']) >= 1
    assert call_kwargs['messages'][0]['role'] == 'system'

API-Fehler in Tests simulieren

Testen Sie, wie Ihr Agent mit LLM-Fehlern umgeht, indem Sie den Mock so konfigurieren, dass er Ausnahmen auslöst. Dadurch überprüfen Sie Ihre Fehlerbehandlung und Wiederholungslogik, ohne echte API-Fehler zu verursachen.

from unittest.mock import patch
import openai

@patch('myagent.client.chat.completions.create')
def test_agent_handles_rate_limit(mock_create):
    # Simulate a rate limit error
    mock_create.side_effect = openai.RateLimitError(
        message='Rate limit exceeded',
        response=None,
        body=None
    )

    from myagent import agent
    result = agent.run('Hello')

    # Agent should handle this gracefully
    assert result['error'] == 'rate_limit'
    # or
    assert result['retry_after'] is not None

Mock-Fixtures in conftest.py organisieren

Platzieren Sie gemeinsame Fixtures in conftest.py im Stammverzeichnis Ihres Testverzeichnisses. pytest erkennt diese Datei automatisch und stellt die Fixtures allen Testdateien zur Verfügung, ohne dass Sie sie importieren müssen.

# tests/conftest.py
import pytest
from unittest.mock import patch, MagicMock

@pytest.fixture(autouse=False)
def mock_llm():
    with patch('myagent.client.chat.completions.create') as mock_create:
        mock_create.return_value = MagicMock(
            choices=[MagicMock(message=MagicMock(
                content='Test response',
                tool_calls=[]
            ))]
        )
        yield mock_create

@pytest.fixture
def mock_search_tool():
    with patch('myagent.tools.search_web') as mock_search:
        mock_search.return_value = [{'title': 'Test', 'url': 'https://example.com'}]
        yield mock_search

Wissenscheck: LLM-Aufrufe mocken

Testen Sie Ihr Verständnis der Mocking-Techniken für Agententests.

Zusammenfassung: LLM-Aufrufe in Tests mocken

Sie verfügen nun über die Werkzeuge, um schnelle und zuverlässige Unit-Tests für Agenten zu schreiben:

  • Verwenden Sie unittest.mock.patch(), um LLM-Clients durch Mocks zu ersetzen
  • Erstellen Sie wiederverwendbare Hilfsfunktionen für Mock-Antworten, die der Antwortstruktur des SDK entsprechen
  • Mocken Sie Tool-Aufrufe mit korrekt strukturierten Feldern tool_calls
  • Verwenden Sie pytest-Fixtures und conftest.py, um Mocks testübergreifend gemeinsam zu nutzen
  • Verwenden Sie pytest-mock für eine übersichtlichere Syntax
  • Verwenden Sie vcrpy, um echte HTTP-Interaktionen aufzuzeichnen und wiederzugeben

Mocks bilden die Grundlage für eine schnelle und wartbare Testsuite für Agenten.

Häufig gestellte Fragen

Ist die Lektion „LLM-Aufrufe in Tests mocken“ kostenlos?

Ja — der vollständige Text von „LLM-Aufrufe in Tests mocken“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „LLM-Aufrufe in Tests mocken“?

unittest.mock, pytest-Fixtures sowie das Aufzeichnen und Wiedergeben von LLM-Responses. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Agents zu starten?

Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „LLM-Aufrufe in Tests mocken“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?

Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Warum das Testen von Agenten anders ist
  2. LLM-Aufrufe in Tests mocken
  3. Assertion-basiertes Agenten-Testing
  4. Integrationstests für Agenten-Pipelines
← Zurück zu AI Agents