Skip to content

refactor(tests): extract canonical make_llm_response fixture — 7+ ad-hoc patterns across the codebase #7134

Closed

Description

@mrveiss

Discovery — 7+ ad-hoc patterns for mocking LLMResponse in tests

While migrating tests across PRs #7101 (chat), #7118 (workflow_documentation), and #7131 (perf benchmarks), a consistent class of duplication surfaced: every test file that needs to fake an LLMResponse from LLMService.chat() invents its own mock pattern.

$ grep -rn "make_llm_response\|class _StubResponse\|MockLLMResponse\|MagicMock(content=" \
    autobot-backend --include="*.py" | grep -v __pycache__ | head -10

Confirmed sites (each uses a different pattern):

File Pattern
tests/orchestration/test_subagent_dispatcher_reflection.py:31 _make_llm_response(content) factory function
tests/fixtures/mocks.py:70 class _MockLLMResponseShim — private, used only inside this file
tests/fixtures/mocks.py:95 _MockLLMResponseShim(content=...) constructor
tests/api/test_knowledge_grounding.py:141,158,683,710,726 Inline MagicMock(content=...) (5 sites)
api/chat_generate_ai_response_test.py (PR #7101) class _StubResponse fixture-local class
orchestration/workflow_documentation_summary_test.py (PR #7118) class _StubResponse (duplicated from #7101)
performance_benchmarks.performance_test.py (PR #7131) Inline MagicMock(content=..., error=None)

7 patterns for the same thing. The contract is uniform — all need:

class _StubLLMResponse:
    content: str
    error: Optional[str]
    model: str = ""
    provider: str = ""

… matching LLMResponse from llm_interface_pkg/models.py:99-112.

Proposal

Extract a single canonical fixture at autobot-backend/tests/fixtures/llm.py (sibling of existing tests/fixtures/mocks.py):

def make_llm_response(
    *, content: str = "", error: str | None = None,
    model: str = "", provider: str = "",
) -> "LLMResponse":
    """Build an LLMResponse-shaped stub for tests.
    
    Returns a real LLMResponse from llm_interface_pkg.models when possible
    (preferred — pins the contract); falls back to MagicMock if importing
    the real class would pull in heavy deps in the test environment.
    """
    try:
        from llm_interface_pkg.models import LLMResponse
        return LLMResponse(content=content, error=error, model=model, provider=provider)
    except ImportError:
        from unittest.mock import MagicMock
        return MagicMock(content=content, error=error, model=model, provider=provider)


@pytest.fixture
def make_llm_response():
    """pytest fixture wrapping the factory above."""
    return make_llm_response  # noqa: F811 — function-as-fixture pattern

Then migrate the 7 sites to import from the canonical location. Existing _MockLLMResponseShim in tests/fixtures/mocks.py is the closest precedent — make it public (drop the underscore), rename to make_llm_response, and have the new fixture file re-export it OR move it.

Acceptance criteria

Why now

Found via

PR #7131 (#7041) audit sweep.

Related

Activity

  1. github-actions commented on May 7, 2026

    @github-actions
    Contributor

    PR #7139 (merged to Dev_new_gui) references this issue with a close keyword.

    refactor(tests): extract canonical make_llm_response fixture (#7134)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  2. mrveiss commented on May 7, 2026

    @mrveiss
    OwnerAuthor

    ✅ Closed with proof of implementation

    Commit: 2b2c2696b (PR #7139)

    Acceptance criteria met:

    • ✅ Canonical make_llm_response() factory + matching pytest fixture in tests/fixtures/mocks.py
    • ✅ Re-exported from tests/fixtures/__init__.py
    • ✅ Real LLMResponse used when importable (pins the field contract)
    • ✅ 7 contract tests including isinstance(LLMResponse) regression pin
    • ✅ Migrated 2 of my own callsites (api/chat_generate_ai_response_test.py, orchestration/workflow_documentation_summary_test.py) onto the canonical fixture

    Out of scope (incremental migration):

    • tests/orchestration/test_subagent_dispatcher_reflection.py:31
    • tests/api/test_knowledge_grounding.py (5 inline MagicMock(content=...))

    Evidence:
    ```
    $ python3 -m pytest \
    tests/fixtures/test_make_llm_response.py \
    api/chat_generate_ai_response_test.py \
    orchestration/workflow_documentation_summary_test.py -xvs
    ============================== 19 passed in 2.58s ===============================
    ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions