What is the difference between the @Spy and @Mock annotations in Mockito?

@Mock and @Spy are Mockito annotations used to create test doubles, but they behave differently. @Mock creates a completely mocked object where no real method execution occurs unless explicitly stubbed, while @Spy creates a partial mock that wraps a real object and executes actual methods unless specific behavior is overridden.

Key Points: • @Mock creates a fully fake object used to isolate dependencies during unit testing. • @Spy creates a partial mock that allows real method execution while selectively mocking certain methods. • @Mock is generally preferred for pure unit testing, whereas @Spy is useful when partial real behavior is required.

Difference Between @Mock and @Spy:

@Mock: • Creates a completely mocked instance. • Real methods are not executed. • Returns default values unless behavior is stubbed. • Best for dependency isolation.

@Spy: • Wraps an actual object instance. • Real methods execute by default. • Specific methods can be mocked when needed. • Useful for partial mocking scenarios.

Code Example:

import static org.mockito.Mockito.*;

class Calculator {

    public int add(int a, int b) {

        return a + b;
    }
}

@Mock
private Calculator mockCalculator;

@Spy
private Calculator spyCalculator =
        new Calculator();

Usage:

when(mockCalculator.add(10, 20))

        .thenReturn(100);

System.out.println(
        mockCalculator.add(10, 20));

Output:

100

System.out.println(
        spyCalculator.add(10, 20));

Output:

30

doReturn(100)

.when(spyCalculator)

        .add(10, 20);

System.out.println(
        spyCalculator.add(10, 20));

Output: 100

Example: Suppose OrderService depends on PaymentService.

• Use @Mock when testing OrderService and you want to completely isolate PaymentService. • Use @Spy when testing a real PaymentService implementation but need to override only a few methods.

When to Use:

Use @Mock: • Unit testing dependencies. • Isolating external systems. • Testing business logic independently.

Use @Spy: • Partial mocking. • Legacy code testing. • Verifying behavior while retaining real method execution.

Interview Tip: A concise interview answer is: @Mock creates a fully mocked object where real methods are not executed, making it ideal for isolating dependencies in unit tests. @Spy creates a partial mock around a real object, allowing actual methods to run unless explicitly stubbed. Use @Mock for pure unit testing and @Spy when only part of an object's behavior needs to be mocked.