Description
MockitoBean
is designed to replace the now-deprecated MockBean
annotation. MockBean
could target either a field or a type. Currently, MockitoBean
can only target a field. This issue proposes adding the support to target types to MockitoBean
, similar to MockBean
.
(pasting some prose from #29917 comments)
This feature is useful for test cases which want to stub out some set of beans (ie to avoid some side effect of regular instantiation), but didn't care about specifying behavior.
Suppose you have multiple
@SpringBootTest
classes, and want to stub out the same set of beans for each of them. With an annotation targeting the class itself, you could define a meta-annotation containing those repeated invocations of MockBean and reuse wherever needed. If we only have support for mocking beans as fields, then the next alternative would be a common superclass which declares those annotated fields. That pattern pushes you to (single) inheritance, whereas the class annotation pattern was composition-friendly.Subjectively, I also think that if the test developer's intent is not to define any behavior for the mocked bean, then it's easier to read and maintain if we can avoid adding an unused field to the class scope.
Here's some Kotlin code to help demonstrate the point above:
@MockBeans(
MockBean(MyServiceWithOutOfProcessSideEffectsOnBoot::class),
MockBean(MyPreemptiveClientAuthTokenFetcher::class),
MockBean(MyServiceWhichLoadsOneMillionThingsIntoMemoryOnBoot::class),
)
annotation class MockExpensiveDependencies
@SpringBootTest
@MockExpensiveDependencies
class BusinessLogicControllerTest {
// ...
}
@SpringBootTest
@MockExpensiveDependencies
class SomeOtherTest {
// ...
}
vs
open class MockExpensiveDependenciesBase {
@MockBean
private lateinit var foo: MyServiceWithOutOfProcessSideEffectsOnBoot
@MockBean
private lateinit var bar: MyPreemptiveClientAuthTokenFetcher
@MockBean
private lateinit var gav: MyServiceWhichLoadsOneMillionThingsIntoMemoryOnBoot
}
@SpringBootTest
class BusinessLogicControllerTest : MockExpensiveDependenciesBase() {
// ...
}
@SpringBootTest
class SomeOtherTest : MockExpensiveDependenciesBase() {
// ...
}