What is the difference between mock() and spy() in Mockito?

mock() and spy() both create test doubles, but mock() produces a fully fake object with no real behavior, while spy() wraps a real object and keeps its original behavior unless a method is explicitly stubbed.

Key Points: • mock() methods return default values (null, 0, false, empty collections) unless stubbed. • spy() delegates to the real object's methods by default, so unstubbed calls execute actual logic. • Stubbing a spy requires doReturn().when(spy) rather than when(spy)... for void or side-effecting methods, to avoid invoking the real method during setup. • spy() is useful for partial mocking - overriding one method while keeping the rest of the real implementation. • Overusing spies can make tests slower and less isolated, since real logic still executes.

Example: Spying on a real ArrayList lets you keep its actual add/get behavior while overriding just size() to return a fixed value for a specific test case.

Code Example:

List<String> spyList = spy(new ArrayList<>());
spyList.add("a");
doReturn(100).when(spyList).size();

assertEquals("a", spyList.get(0));
assertEquals(100, spyList.size());

Interview Tip: A concise interview answer is:

"mock() creates a fake object where every method does nothing unless stubbed, while spy() wraps a real instance so unstubbed methods still run their actual implementation. I reach for spy() when I need most of an object's real behavior but want to override one specific method."