Skip to content

Support @MockitoBean at the type level on test classes #33925

Closed
@nmck257

Description

@nmck257

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() {
    // ...
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions