# PR#136: MockK Mocks Cleared after Every Spec > **WARNING:** This document describes only the change applied in this PR. > It may already be outdated once the next PR is merged. > Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation. ## The Problem The nightly mutation build of 2026-10-10 passed the Mutation-CRAP limit of 15 for the first time, but still went red. One mutant in `Watcher.pruneWorktrees` ended in `MEMORY_ERROR`, so werkcrappit found its method `INCONCLUSIVE` and refused the gate. The mutant itself is harmless: applied by hand, `WatcherUnitTest` kills it with two failing tests. A local PIT run of `Watcher` alone, with the heap of a minion on mih09 (1484 MiB, a quarter of its RAM), ended the same mutant in `MEMORY_ERROR`. With 3 GiB of heap, PIT killed it. PIT runs all 190 mutants of `Watcher` in one minion, and for each mutant it runs the whole spec again. The live heap of that minion grew by about 200 MB every 15 seconds, also right after a full GC. After 70 seconds, a class histogram showed 123147 live `MockKStub` objects: every mock the minion had ever created. MockK holds its stubs only weakly, but the answers and recorded calls of a stub point back to its mock. So the weak registries never let a mock go. A normal test run is short enough not to notice, but a minion runs every spec a few hundred times. ## Non-Goals - Finding out why MockK still keeps the emptied stubs. An emptied stub is small: with the fix, the heap of the minion grows four times slower, and no mutant ends in `MEMORY_ERROR`. ## The Scenarios #### Scenario#136.01: A spec clears its mocks when it ends - **Given** a spec with a mock that has an answer and a recorded call - **When** the spec ends - **Then** the mock has neither - **So that** old mocks do not fill the heap of a PIT minion. ##### Verified by - [ReleaseMocksAfterSpecUnitTest](../../src/test/kotlin/de/hoennig/werkator/framework/ReleaseMocksAfterSpecUnitTest.kt) ## The Solution - The Kotest project configuration registers `ReleaseMocksAfterSpec`, which calls `clearAllMocks()` after every spec. - After a spec, not after a test: a spec may stub its mocks once for all its tests. No spec stubs a mock in a bean definition, so a Spring context cached for the next spec loses nothing it needs. The same local PIT run of `Watcher`, with 1484 MiB and the fix: | Run | Live heap growth (after full GC) | Mutants in `MEMORY_ERROR` | |------------------------|----------------------------------|--------------------------:| | Without the fix | about 200 MB per 15 s | 1 | | With `clearAllMocks()` | about 45 MB per 15 s | 0 | ## Follow-up PRs - A heap limit for the minions that fits, measured with a full run now that the mocks are released (see PR#135).