Skip to content

fix #22: [13] Tests mock the wrong code path — assertions never fail even when code is broken - #46

Merged
CuriosityQuantified merged 1 commit into
mainfrom
feat/22-fix-llm-service-mock-path
Aug 9, 2026
Merged

CuriosityQuantified merged 1 commit into
mainfrom
feat/22-fix-llm-service-mock-path

Conversation

@CuriosityQuantified

Copy link
Copy Markdown
Owner

Closes #22

Problem

tests/unit/test_llm_service.py::test_create_idea_final_turn_conclusion_parsing (and its module-level fallback companion) patched service.groq_client — a direct Groq SDK instance — and asserted service.groq_client.chat.completions.create.assert_called_once(). But create_idea never calls self.groq_client; it drives LangChain's LLMChain.arun() on a ChatGroq instance (services/llm_service.py:313/:318). The patch intercepted nothing, so the assertions could never fail even if the real code broke. The tests also asserted the stale model id qwen-qwq-32b (now moonshotai/kimi-k2-instruct) and treated create_idea's single-dict return as a list.

Fix

  • Patch langchain.chains.LLMChain.arun with AsyncMock so both final-turn tests exercise the real code path. Verified by mutation test: changing models_to_try now fails the test, proving the assertions bite.
  • Remove the dead groq_client mocks/assertions.
  • Update model-name expectations to the current moonshotai/kimi-k2-instruct.
  • Handle create_idea's single-dict return correctly (it returns a dict, not a list).
  • Remove the dead nested duplicate test_create_idea_final_turn_fallback_parsing defined inside test_create_idea_live_groq_call (never collected by pytest).

CI

Scope

Only tests/unit/test_llm_service.py and .github/workflows/ci.yml changed. No LCEL migration or dependency changes (#24's territory). No production code changed.

Gates run locally

  • Focused regression (both final-turn tests): 2 passed.
  • Full Python unit suite mirroring CI deselects: 228 passed, 1 skipped, 6 deselected.
  • npm run build (Next.js production build): success.
  • Playwright e2e "Regressions" job not run locally: the diff touches no frontend/e2e/Playwright code; the Build gate covers the Next.js side. CI will run it.

Graphify: N/A — repo has no .mcp.json, graphify-out/, or code-graph CI job.

🤖 Generated with Claude Code

…even when code is broken

test_create_idea_final_turn_conclusion_parsing (and its fallback
companion) patched service.groq_client and asserted on
groq_client.chat.completions.create, but create_idea never touches the
Groq SDK — it drives LangChain's LLMChain.arun (a ChatGroq instance).
The patch intercepted nothing, so the assertions could never fail even
if the real code broke. The tests also asserted the stale model id
"qwen-qwq-32b" and treated create_idea's single-dict return as a list.

- Patch langchain.chains.LLMChain.arun with AsyncMock so the tests
  exercise the real code path; a mutation of models_to_try now fails
  the test, proving the assertions bite.
- Remove the dead groq_client mocks/assertions.
- Update model-name expectations to the current "moonshotai/kimi-k2-instruct".
- Handle create_idea's single-dict return correctly (not a list).
- Remove the dead nested duplicate test_create_idea_final_turn_fallback_parsing
  defined inside test_create_idea_live_groq_call (never collected).
- CI: run the two now-fixed tests (remove their deselects), add a named
  "Run LLM service final-turn parsing regression" step, and fix the
  mislabeled deselect comment.

Closes #22

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
save-the-world Ready Ready Preview Aug 9, 2026 10:01pm
sim-local Ready Ready Preview Aug 9, 2026 10:01pm

@CuriosityQuantified
CuriosityQuantified merged commit d275ebf into main Aug 9, 2026
6 checks passed
@CuriosityQuantified
CuriosityQuantified deleted the feat/22-fix-llm-service-mock-path branch August 9, 2026 22:04
CuriosityQuantified added a commit that referenced this pull request Aug 10, 2026
Issue #23 reported a `test_*` function defined *inside* another test
function in tests/unit/test_llm_service.py. Pytest only collects
module-level functions and Test*-class methods, so the nested copy was
never run -- dead code masquerading as fallback-parsing coverage.

The literal deletion already landed via PR #46 (commit d275ebf, which
closed #22) as a side-effect of the same-file mock fix, so nothing is
left to delete. What was still missing is a guard against recurrence,
which this PR adds following the repo's per-issue regression convention.

- tests/unit/test_nested_test_discovery_regression.py: AST-based,
  offline (parses, never imports/execs) guard that scans every
  tests/unit/test_*.py and fails if any `test_*` function is nested
  inside another function. Class-body scopes reset the enclosing-function
  context so Test*-class methods stay allowed. Two targeted assertions
  lock in the exact #23 fix: `test_create_idea_final_turn_fallback_parsing`
  is defined exactly once at module level and is not nested inside
  `test_create_idea_live_groq_call`.
- .github/workflows/ci.yml: add a named "Run nested test discovery
  regression" step in the unit-tests job, mirroring the sibling
  per-issue regression steps. Deselect list and other jobs untouched.

Local gates: unit suite 231 passed / 1 skipped / 6 deselected (was 228;
+3 new); Next.js `npm run build` green. No graphify-out/ or code-graph
CI job in this repo, so graph refresh is not applicable.

Closes #23

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[13] Tests mock the wrong code path — assertions never fail even when code is broken

1 participant