Unit testing 如何使用@MockBean而不必再次@injectthebean?

Unit testing 如何使用@MockBean而不必再次@injectthebean?,unit-testing,junit,micronaut,mockk,Unit Testing,Junit,Micronaut,Mockk,在Micronaut中是否有更简洁/优雅的方式实现此功能 @MicronautTest class ControllerTest { @Inject @field:Client("/") lateinit var client: RxHttpClient @Inject lateinit var redeemService: RedeemService @MockBean(RedeemService::class)

在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
,这似乎是多余的工作。 我记得,在SpringBoot中,这只是一个
lateinit var
上的注释


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

您需要模拟bean来替换服务并将其注入应用程序中的任何地方。。如果您想做一些验证,您必须将其注入回类中,或者在类中创建实例,并使用模拟bean返回该实例

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

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

您需要模拟bean来替换服务并将其注入应用程序中的任何地方。。如果您想做一些验证,您必须将其注入回类中,或者在类中创建实例,并使用模拟bean返回该实例

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

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

通常,
MockBean
是不可操作的协作者,旨在被划分为依赖bean,而不是依赖于具体的bean实现

如果在测试夹具~您的测试功能范围~内,您必须验证协作者调用或为其他协作者调用提供自定义响应,则必须将其注入

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

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


简而言之,如果您的bean(模拟的或具体的)通过
@Inject
注释进入测试实现,那么您可以确信,当注入到实际应用程序代码中时,它将同样工作,因为测试夹具本身就是bean。

通常,
MockBean
是不可操作的协作者,旨在被划分为依赖bean,而不是依赖于具体的bean实现

如果在测试夹具~您的测试功能范围~内,您必须验证协作者调用或为其他协作者调用提供自定义响应,则必须将其注入

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

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


简言之,如果您的bean(模拟的或具体的)通过
@Inject
注释进入您的测试实现,那么您可以确信,当注入到实际应用程序代码中时,它将同样工作,因为测试夹具本身就是一个bean。

我猜这是一个有效的解决方案。如果有其他答案,我会再等几天,否则我会接受这个答案。谢谢我想这是一个有效的解决办法。如果有其他答案,我会再等几天,否则我会接受这个答案。谢谢“对我来说,必须声明MockBean,然后还要注入之前声明的MockBean,这看起来像是多余的工作”——通常mock不会注入到测试中,而是注入到被测试的组件中。在您的情况下,您的测试不会测试除模拟本身之外的任何东西,因此不清楚您真正想要完成的是什么。我猜模拟可以用于两个目的:将单元的行为与系统的其余部分隔离+捕获跨越此边界的信息(以及频率等)。对我来说,经常使用这两个特性是完全正常的,这就是为什么我也在Micronaut中搜索类似的东西。“对我来说,必须声明MockBean,然后还要注入之前声明的MockBean,这看起来像是多余的工作”-通常模拟不会注入测试,它被注入正在测试的组件中。在您的情况下,您的测试不会测试除模拟本身之外的任何东西,因此不清楚您真正想要完成的是什么。我猜模拟可以用于两个目的:将单元的行为与系统的其余部分隔离+捕获跨越此边界的信息(以及频率等)。对我来说,经常使用这两种功能是完全正常的,这就是为什么我也在Micronaut中寻找类似的东西。那么你会说这是一个设计缺陷吗?在我谦逊的vue观点中,是的。Micronaut可以帮助你避免它。那么你会说这是一个设计缺陷吗?在我谦逊的vue观点中,是的。Micronaut可以帮助您避免这种情况。