From e2720941476d5cc04e484ca266e344e7e58f4b2f Mon Sep 17 00:00:00 2001 From: Glen Beane <356266+gbeane@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:10:42 -0400 Subject: [PATCH] Document actual test mocking convention (monkeypatch + unittest.mock) --- CLAUDE.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 55910206..5948f45c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -265,7 +265,10 @@ Every module should have a **clear, single responsibility**. If a module docstri ### Framework & Tools -- **pytest** (plain functions, no unittest-style classes), **pytest-cov**, **pytest-mock** +- **pytest** (plain functions, no unittest-style classes), **pytest-cov** +- **Mocking:** use the built-in **`monkeypatch`** fixture and the standard-library + **`unittest.mock`**. `pytest-mock` (the `mocker` fixture) is **not** a dependency — do + not use it. - Run coverage: `uv run pytest --cov=src/jabs --cov-report=term-missing` ### Test Organization @@ -287,15 +290,25 @@ def test_normalize_distance_basic() -> None: result = normalize_distance(distance=50.0, arena_diameter=100.0) assert result == pytest.approx(0.5) -# Mock external dependencies — never hit filesystem, network, or GPU in unit tests -def test_classifier_predict(mocker: MockerFixture) -> None: - mock_model = mocker.Mock() +# Mock external dependencies — never hit filesystem, network, or GPU in unit tests. +# Use unittest.mock for standalone mocks; use monkeypatch to patch module-level symbols. +from unittest import mock + +def test_classifier_predict() -> None: + mock_model = mock.Mock() mock_model.predict.return_value = np.array([0, 1, 0]) classifier = BehaviorClassifier(model=mock_model) predictions = classifier.predict(features) mock_model.predict.assert_called_once() assert len(predictions) == 3 +# Patch a function/attribute for the duration of one test (auto-undone) with monkeypatch +def test_export_calls_save(monkeypatch) -> None: + save_spy = mock.Mock() + monkeypatch.setattr("jabs.io.save", save_spy) + export_training_data(project) + save_spy.assert_called_once() + # Use fixtures extensively for shared setup (in conftest.py) @pytest.fixture def sample_pose_array() -> npt.NDArray[np.float64]: