如何使用@MockBean 而不必再次@Inject Bean?

How to use @MockBean without having to @Inject the Bean again?

在 Micronaut 中是否有更简洁/优雅的方式来实现此功能?

@MicronautTest
class ControllerTest {
    @Inject
    @field:Client("/")
    lateinit var client: RxHttpClient

    @Inject
    lateinit var redeemService: RedeemService

    @MockBean(RedeemService::class)
    fun redeemService(): RedeemService = mockk {
        every { validate(any()) } returns true
    }

    @Test
    fun test() {
        // some logic triggering a call to redeemService
        verify(exactly = 1) {
            redeemService.validate("123")
        }
    }
}

对我来说,必须声明 @MockBean 然后还必须 @Inject 之前声明的 @MockBean 似乎是多余的工作。 据我所知,在 Spring Boot 中,这只是 lateinit var.

上的注释

我是否误解或忽略了什么?

您需要模拟 bean,用于替换服务并将其注入应用程序中的任何位置.. 如果您想进行一些验证,您必须将其注入或在 class 和 return 模拟 bean

private val redeemService: RedeemService = mockk {
    every { validate(any()) } returns true
}

@MockBean(RedeemService::class)
fun redeemService() = redeemService

通常,MockBean 是 NO-OP 协作者,它们旨在被 DI 化为依赖 bean,而不是依赖于具体的 bean 实现。

如果在测试夹具中~你测试的功能范围~你必须验证协作者调用或为其他协作者调用提供自定义响应,那么你必须注入它。

如前所述,这可能看起来像冗余,但事实并非如此,并且应该以这种方式完成,否则 Micronaut(或任何其他这样做的框架)会有一点设计缺陷。

依赖自定义实现(在本例中为注解)作为测试中的 bean 提供者和注入点将导致不确定的行为和内部与框架特性的紧密耦合,因为您将在测试中注入依赖项fixture 与您在实际应用程序代码中的处理方式不同,应该避免这种情况。

简而言之,如果您的 bean(模拟的或具体的)通过 @Inject 注释进入您的测试实现,那么您可以放心,自测试以来将其注入真实应用程序代码时,它的工作方式是一样的fixture 本身就是一个 bean。