Mocking in Java
Mockito Framework
Spring Boot Testing
Unit Testing
Java Annotations

Difference between @Mock, @MockBean and Mockito.mock()

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In the realm of Java testing, particularly when using the Spring framework and JUnit, you might have encountered annotations like @Mock, @MockBean, and also the method Mockito.mock(). These are commonly used for creating mock objects that help in isolating test subjects by replacing dependencies with objects that simulate the behaviors of those dependencies. Understanding the differences and appropriate use cases of each can significantly smooth out the testing process and improve code maintainability.

Understanding @Mock

The @Mock annotation is part of the Mockito library. It is used to create and inject mock instances without having to manually call the Mockito.mock() method. Mocks created with this annotation are suitable for simple unit tests where no Spring context is loaded. It offers straightforward way to replace a dependency, focusing purely on the functionality of the class under test.

Here’s a brief example using @Mock:

java
1@RunWith(MockitoJUnitRunner.class)
2public class SimpleServiceTest {
3
4    @Mock
5    private Dependency dependency;
6
7    @InjectMocks
8    private SimpleService simpleService;
9
10    @Test
11    public void testMethod() {
12        when(dependency.method()).thenReturn("Mocked Response");
13        assertEquals("Mocked Response", simpleService.method());
14    }
15}

In this example, Dependency is a mock purely for the scope of this test, managed by Mockito without any Spring intervention.

Understanding @MockBean

On the other hand, @MockBean is specific to Spring Boot tests. It adds Mockito mock support in tests run with Spring's testing support. When you declare a mock with @MockBean, it replaces any existing bean of the same type in the Spring application context. If no bean of that type is defined, a new one will be added. This is particularly useful when you need to integrate with Spring context and have dependencies that need to be mocked in integration tests.

Here’s an example of @MockBean:

java
1@RunWith(SpringRunner.class)
2@SpringBootTest
3public class SpringServiceTest {
4
5    @MockBean
6    private Dependency dependency;
7
8    @Autowired
9    private SpringService springService;
10
11    @Test
12    public void testMethod() {
13        when(dependency.method()).thenReturn("Mocked Response");
14        assertEquals("Mocked Response", springService.method());
15    }
16}

In this case, Dependency is part of the Spring context, and the mock is managed throughout the Spring lifecycle, which is more complex than pure unit tests.

Understanding Mockito.mock()

Finally, Mockito.mock() is the basic method provided by Mockito to create mock objects programmatically. This approach is very flexible and can be used in any kind of test. It doesn’t integrate with Spring or any other framework. It’s purely a Mockito functionality.

Example:

java
1public class GeneralTest {
2    @Test
3    public void testMethod() {
4        Dependency dependency = Mockito.mock(Dependency.class);
5        SimpleService simpleService = new SimpleService(dependency);
6
7        when(dependency.method()).thenReturn("Mocked Response");
8        assertEquals("Mocked Response", simpleService.method());
9    }
10}

Comparison Table

Feature/Usage@Mock@MockBeanMockito.mock()
FrameworkMockitoSpring Boot TestsMockito
ScopeClass level (with runner or rule)Spring ApplicationContextCan be used anywhere
Best UseUnit tests without SpringIntegration tests with Spring contextFlexible, non-Spring specific tests
Lifecycle managementManaged by MockitoManaged by SpringManual by the developer

Summary

  • @Mock is best used for simple unit tests where Spring context is not required.
  • @MockBean is ideal for Spring Boot applications when you need mocks integrated within Spring's context for broader testing, including controllers and other components interconnected in the Spring environment.
  • Mockito.mock() offers the most control and flexibility, usable in any setup, but requires manual management and is not integrated into any particular testing framework or lifecycle.

Understanding when to use each of these can lead to cleaner, more efficient tests that are both easier to write and maintain.


Course illustration
Course illustration

All Rights Reserved.