Stub use State Verification
which means that we determine whether the exercised method worked correctly by examining the state of SUT (system under test) and its collaborators after the method was exercised.
Mock use Behavior Verification
do the check by telling the mock what to expect during setup and ask the mock to verify itself during verification.
Classical and Mockist Testing
The classical TDD style is to use the real objects if possible and a double if it's awkward to use the real thing.
So a classical TDDer would use a real warehouse and a double for the mail service. The kind of double doesn't really matter that much.
A mockist TDD practitioner, however, will always use a mock for any object with interesting behavior. In this case for both the warehouse and the mail service.