A stub and a mock are both test doubles used to replace real objects, but they differ in intent: a stub simply provides canned answers to calls, while a mock verifies that specific interactions actually happened.
Key Points: • A stub returns pre-programmed values and has no expectations about how it is called. • A mock records interactions and lets the test assert on calls, arguments, and call counts. • Stubs support state verification (checking the result), mocks support behavior verification (checking the interaction). • In Mockito, mock() objects can behave as either a stub or a mock depending on whether you use when()/thenReturn() or verify(). • Overusing mocks for behavior that could be tested via return values leads to brittle tests tied to implementation details.
Example: If you replace a PaymentGateway with a stub that always returns true from charge(), you're just supplying test data; if instead you assert that charge() was called exactly once with a specific amount using verify(), you're using it as a mock.
Interview Tip: A concise interview answer is:
"A stub is a test double that returns canned responses so you can test the state produced by your code, while a mock additionally lets you verify that specific interactions - method calls, arguments, and call counts - actually occurred. In Mockito the same mock() object can serve as a stub via when()/thenReturn() or as a true mock via verify()."