A mock that records is a stub with a receipt

A stub provides answers and a mock asserts on the calls, and conflating them produces tests that break when the implementation is refactored.

// a stub: the test needs a value, not a verification
$repo = $this->createStub(OrderRepository::class);
$repo->method('find')->willReturn($order);

// a mock: the interaction IS the behaviour under test
$mailer = $this->createMock(Mailer::class);
$mailer->expects($this->once())
    ->method('send')
    ->with($this->callback(fn ($m) => $m->to() === '[email protected]'));

Asserting on a call that is incidental to the behaviour couples the test to how the code works rather than what it does, so a refactor that changes nothing observable breaks a dozen tests and everybody learns to distrust them. The rule that holds up is to mock the calls that are the observable effect — sending an email, charging a card, publishing an event — and stub everything else.