Explain the difference between @Mock and @InjectMocks in Mockito.?

In Mockito, @Mock and @InjectMocks serve different purposes during unit testing. @Mock is used to create mock objects that simulate the behavior of real dependencies, while @InjectMocks is used to create the class under test and automatically inject the mocked dependencies into it.

Key Points: • @Mock creates fake implementations of dependencies. • @InjectMocks creates the actual object being tested. • Mockito automatically injects mock objects into the class annotated with @InjectMocks. • Using both annotations helps isolate business logic from external dependencies. • They are commonly used together in unit testing.

What is @Mock?

@Mock creates a dummy or simulated version of a dependency.

Instead of calling the real implementation, the test interacts with the mock object.

Example:

Suppose EmployeeService depends on EmployeeRepository.

Code Example:

@Mock
private EmployeeRepository repository;

Here:

• No real database call is made. • The repository behavior can be controlled during testing. • The test remains fast and isolated.

What is @InjectMocks?

@InjectMocks creates the actual object that we want to test.

Mockito automatically injects all matching mock dependencies into this object.

Code Example:

@InjectMocks
private EmployeeService employeeService;

Mockito will create EmployeeService and inject the mocked EmployeeRepository into it.

How They Work Together

Code Example:

@Mock
private EmployeeRepository repository;

@InjectMocks
private EmployeeService employeeService;

Mockito Process:

1. Create mock EmployeeRepository. 2. Create EmployeeService. 3. Inject mocked repository into EmployeeService.

Result:

EmployeeService | Mock EmployeeRepository

No real repository implementation is used.

Practical Example

Code Example:

@Service
public class EmployeeService {

    private final EmployeeRepository repository;

    public EmployeeService(
            EmployeeRepository repository) {

        this.repository = repository;
    }

    public Employee getEmployee(
            Long id) {

return repository.findById(id)

                .orElse(null);
    }
}

Unit Test:

Code Example:

@ExtendWith(MockitoExtension.class)
class EmployeeServiceTest {

    @Mock
    private EmployeeRepository repository;

    @InjectMocks
    private EmployeeService employeeService;

    @Test
    void testGetEmployee() {

        Employee employee =
                new Employee(1L, "John");

when(repository.findById(1L))

                .thenReturn(
                        Optional.of(employee));

        Employee result =
                employeeService.getEmployee(1L);

        assertEquals(
                "John",
                result.getName());
    }
}

In this test:

• EmployeeService is real. • EmployeeRepository is mocked. • No database interaction occurs.

Comparison

@Mock

• Creates fake objects. • Used for dependencies. • Behavior is controlled using Mockito methods.

@InjectMocks

• Creates the actual object under test. • Injects mocks automatically. • Used for testing business logic.

How Injection Happens

Mockito supports:

• Constructor Injection • Setter Injection • Field Injection

Mockito prefers constructor injection whenever possible.

Example: Suppose we are testing:

OrderService

Dependencies:

• OrderRepository • PaymentService

Unit Test Setup:

@Mock
private OrderRepository repository;

@Mock
private PaymentService paymentService;

@InjectMocks
private OrderService orderService;

Mockito creates:

OrderService | |---- Mock OrderRepository | |---- Mock PaymentService

This allows testing OrderService independently.

Benefits

• Faster unit tests • No database dependency • No external service dependency • Better isolation • Easier debugging

Real-World Example

In a banking application:

TransferService depends on:

• AccountRepository • NotificationService

During unit testing:

• Both dependencies are mocked using @Mock. • TransferService is created using @InjectMocks.

This allows testing transfer logic without accessing databases or sending real notifications.

Interview Tip: A concise interview answer is:

"@Mock is used to create mock versions of dependencies, while @InjectMocks creates the actual class under test and automatically injects those mock dependencies into it. Typically, @Mock is used for collaborators, and @InjectMocks is used for the service or component whose business logic we want to test."