Compute what to do, then do it — in two separate functions. Shape effectful work as fetch → decide → execute:
decideis pure (values in, a description of the work out),executejust walks that description with no branching.
Unit-test the pure part with plain data in / plain data out; the shell is covered by integration tests. No mocks, stubs, spies or doubles — including collaborators injected only so tests can pass a fake. If you find yourself asserting that a method was called, split the function instead.