Stubs replace inbound interactions from dependencies to the SUT. They provide canned responses so the test controls what the SUT sees. The critical rule: do not assert on outbound calls to a stub. That call is an implementation detail. If a refactor caches a previously fetched value, asserting on the stub call causes test failures with no behavior change. This is over-specification.
When using a stub, consider whether a fake is better. A fake implements the same API with a lightweight backing store (a Dict instead of a database, for example). Fakes are more robust to refactoring and more extensible than stubs with preconfigured return values, because they donβt require resetting or ordered canned responses for different user journeys.