It is currently possible for one Bean Override to override another
logically equivalent Bean Override.
For example, a @TestBean can override a @MockitoBean, and vice versa.
In fact, it's also possible for a @MockitoBean to override another
@MockitoBean, for a @TestBean to override a @TestBean, etc.
However, there may be viable use cases for one override overriding
another override. For example, one may have a need to spy on a bean
created by a @TestBean factory method.
In light of that, we do not prohibit one Bean Override from overriding
another Bean Override; however, with this commit we now log a warning
to help developers diagnose issues in case such an override is
unintentional.
For example, given the following test class, where TestConfig registers
a single bean of type MyService named "myService"...
@SpringJUnitConfig(TestConfig.class)
class MyTests {
@TestBean(methodName = "example.TestUtils#createMyService")
MyService testService;
@MockitoBean
MyService mockService;
@Test
void test() {
// ...
}
}
... running that test class results in a log message similar to the
following, which has been formatted for readability.
WARN - Bean with name 'myService' was overridden by multiple handlers:
[
[TestBeanOverrideHandler@44b21f9f
field = example.MyService example.MyTests.testService,
beanType = example.MyService,
beanName = [null],
strategy = REPLACE_OR_CREATE
],
[MockitoBeanOverrideHandler@7ee8130e
field = example.MyService example.MyTests.mockService,
beanType = example.MyService,
beanName = [null],
strategy = REPLACE_OR_CREATE,
reset = AFTER,
extraInterfaces = set[[empty]],
answers = RETURNS_DEFAULTS, serializable = false
]
]
NOTE: The last registered BeanOverrideHandler wins. In the above
example, that means that @MockitoBean overrides @TestBean, resulting
in a Mockito mock for the MyService bean in the test's
ApplicationContext.
Closes gh-34056