Test Behavior, Not Implementation
Focus on what the code does for its users, not how it does it. Private methods and call sequences matter only when they're part of the contract you're guaranteeing.
One Clear Failure Reason
Each test should fail for exactly one conceptual reason. If you need conditionals in your test, you're probably testing multiple scenarios—split them or move up to integration level.
Strategic Test Doubles
Mock what's slow, flaky, or expensive. Everything else should use real objects when practical. Over-mocking makes tests brittle; under-mocking makes them slow.