|
This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.12! |
@MockitoBean and @MockitoSpyBean
@MockitoBean and
@MockitoSpyBean
can be used in test classes to override a bean in the test’s ApplicationContext with a
Mockito mock or spy, respectively. In the latter case, an early instance of the
original bean is captured and wrapped by the spy.
The annotations can be applied in the following ways.
-
On a non-static field in a test class or any of its superclasses.
-
On a non-static field in an enclosing class for a
@Nestedtest class or in any class in the type hierarchy or enclosing class hierarchy above the@Nestedtest class. -
At the type level on a test class or any superclass or implemented interface in the type hierarchy above the test class.
-
At the type level on an enclosing class for a
@Nestedtest class or on any class or interface in the type hierarchy or enclosing class hierarchy above the@Nestedtest class.
When @MockitoBean or @MockitoSpyBean is declared on a field, the bean to mock or spy
is inferred from the type of the annotated field. If multiple candidates exist in the
ApplicationContext, a @Qualifier annotation can be declared on the field to help
disambiguate. In the absence of a @Qualifier annotation, the name of the annotated
field will be used as a fallback qualifier. Alternatively, you can explicitly specify a
bean name to mock or spy by setting the value or name attribute in the annotation.
When @MockitoBean or @MockitoSpyBean is declared at the type level, the type of bean
(or beans) to mock or spy must be supplied via the types attribute in the annotation –
for example, @MockitoBean(types = {OrderService.class, UserService.class}). If multiple
candidates exist in the ApplicationContext, you can explicitly specify a bean name to
mock or spy by setting the name attribute. Note, however, that the types attribute
must contain a single type if an explicit bean name is configured – for example,
@MockitoBean(name = "ps1", types = PrintingService.class).
To support reuse of mock configuration, @MockitoBean and @MockitoSpyBean may be used
as meta-annotations to create custom composed annotations – for example, to define
common mock or spy configuration in a single annotation that can be reused across a test
suite. @MockitoBean and @MockitoSpyBean can also be used as repeatable annotations at
the type level — for example, to mock or spy several beans by name.
|
Qualifiers, including the name of a field, are used to determine if a separate
|
|
Using See context hierarchies with bean overrides for further details and examples. |
Each annotation also defines Mockito-specific attributes to fine-tune the mocking behavior.
The @MockitoBean annotation uses the REPLACE_OR_CREATE
strategy for bean overrides.
If a corresponding bean does not exist, a new bean will be created. However, you can
switch to the REPLACE strategy by setting the enforceOverride attribute to true –
for example, @MockitoBean(enforceOverride = true).
The @MockitoSpyBean annotation uses the WRAP
strategy,
and the original instance is wrapped in a Mockito spy. This strategy requires that
exactly one candidate bean exists.
|
As stated in the documentation for Mockito, there are times when using To avoid such undesired side effects, consider using
|
|
When using Similarly, when using When using Similarly, when using |
|
There are no restrictions on the visibility of Such fields can therefore be |
@MockitoBean Examples
The following example shows how to use the default behavior of the @MockitoBean
annotation.
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean (1)
CustomService customService;
// tests...
}
| 1 | Replace the bean with type CustomService with a Mockito mock. |
In the example above, we are creating a mock for CustomService. If more than one bean
of that type exists, the bean named customService is considered. Otherwise, the test
will fail, and you will need to provide a qualifier of some sort to identify which of the
CustomService beans you want to override. If no such bean exists, a bean will be
created with an auto-generated bean name.
The following example uses a by-name lookup, rather than a by-type lookup. If no bean
named service exists, one is created.
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean("service") (1)
CustomService customService;
// tests...
}
| 1 | Replace the bean named service with a Mockito mock. |
The following @SharedMocks annotation registers two mocks by-type and one mock by-name.
-
Java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoBean(types = {OrderService.class, UserService.class}) (1)
@MockitoBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedMocks {
}
| 1 | Register OrderService and UserService mocks by-type. |
| 2 | Register PrintingService mock by-name. |
The following demonstrates how @SharedMocks can be used on a test class.
-
Java
@SpringJUnitConfig(TestConfig.class)
@SharedMocks (1)
class BeanOverrideTests {
@Autowired OrderService orderService; (2)
@Autowired UserService userService; (2)
@Autowired PrintingService ps1; (2)
// Inject other components that rely on the mocks.
@Test
void testThatDependsOnMocks() {
// ...
}
}
| 1 | Register common mocks via the custom @SharedMocks annotation. |
| 2 | Optionally inject mocks to stub or verify them. |
The mocks can also be injected into @Configuration classes or other test-related
components in the ApplicationContext in order to configure them with Mockito’s stubbing
APIs.
|
@MockitoSpyBean Examples
The following example shows how to use the default behavior of the @MockitoSpyBean
annotation.
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean (1)
CustomService customService;
// tests...
}
| 1 | Wrap the bean with type CustomService with a Mockito spy. |
In the example above, we are wrapping the bean with type CustomService. If more than
one bean of that type exists, the bean named customService is considered. Otherwise,
the test will fail, and you will need to provide a qualifier of some sort to identify
which of the CustomService beans you want to spy.
The following example uses a by-name lookup, rather than a by-type lookup.
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean("service") (1)
CustomService customService;
// tests...
}
| 1 | Wrap the bean named service with a Mockito spy. |
The following @SharedSpies annotation registers two spies by-type and one spy by-name.
-
Java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoSpyBean(types = {OrderService.class, UserService.class}) (1)
@MockitoSpyBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedSpies {
}
| 1 | Register OrderService and UserService spies by-type. |
| 2 | Register PrintingService spy by-name. |
The following demonstrates how @SharedSpies can be used on a test class.
-
Java
@SpringJUnitConfig(TestConfig.class)
@SharedSpies (1)
class BeanOverrideTests {
@Autowired OrderService orderService; (2)
@Autowired UserService userService; (2)
@Autowired PrintingService ps1; (2)
// Inject other components that rely on the spies.
@Test
void testThatDependsOnMocks() {
// ...
}
}
| 1 | Register common spies via the custom @SharedSpies annotation. |
| 2 | Optionally inject spies to stub or verify them. |
The spies can also be injected into @Configuration classes or other test-related
components in the ApplicationContext in order to configure them with Mockito’s stubbing
APIs.
|