【问题标题】:How to mock the ApplicationContext in companion object in kotlin?如何在 kotlin 的伴生对象中模拟 ApplicationContext?
【发布时间】:2022-01-16 08:42:00
【问题描述】:

帮助测试调用类方法的函数。 有一个类,它的字段是用一系列方法 appContext().getBean() 初始化的。

class ClassA {
    private val employeeApi: EmployeeApi= appContext().getBean()
    fun execute(): List<Employee> {
        return employeeApi.method()
    }
}

例如,有一个调用类方法的函数。

    fun methodForTesting(params: ClassA .() -> Unit): List<Employee> {
         return ClassA().apply(params).execute()
    }

此功能需要测试。怎么做?

  1. 使用打开对文件中方法的访问 mockkStatic("com.company.MyFile")
  2. 创建需要返回的工人列表
  3. 创建方法存根
  4. 调用方法
  5. 检查数据

@测试

fun `methodForTesting mockk`() {
    mockkStatic("com.company.MyFile")
    val classA : ClassA= Mockito.mock(ClassA::class.java)
    val listEmployee: List<Employee>  = listOf(Employee("Ivan"))
    Mockito.`when`(classA.execute()).thenReturn(listEmployee)

    val list : List<Employee> = methodForTesting(allAny())

    Assertions.assertThat(list).isEqualTo(listEmployee)
}

如果我这样写,就会发生错误。如何最终确定解决方案?

错误: kotlin.UninitializedPropertyAccessException:lateinit 属性 FIELD 尚未初始化 在 Mockito.when(classA.execute()).thenReturn(listEmployee)

Configuration
EnableConfigurationProperties(HurmaProperties::class)
class AppConfig : ApplicationContextAware {
    private var applicationContext: ApplicationContext? = null

    override fun setApplicationContext(applicationContext: ApplicationContext) {
        this.applicationContext = applicationContext
        appCtx = applicationContext
    }

    @Bean
    fun restTemplateBuilder(): RestTemplateBuilder = RestTemplateBuilder()

    @Bean
    fun restTemplate(builder: RestTemplateBuilder): RestTemplate =
        builder.build()

    companion object {
        @JvmStatic
        lateinit var appCtx: ApplicationContext
            private set
    }
}

fun appContext() = AppConfig.appCtx

【问题讨论】:

  • 您使用 ApplicationContext.getBean() 的原因是什么?这是非常不标准的,我真的想不出这样做的理由,而不是使用弹簧的常规自动装配注入。如果您使用默认注入方式,您可以在测试中提供自定义 Bean,以便它们自动注入,而无需模拟任何东西。

标签: kotlin mockk


【解决方案1】:

我想通了 如果你从 ApplicationContext 调用 getBean(),并且你需要测试一些方法,那么这样做:

var employeeApi = mock<EmployeeApi>()
every { appContext().getBean<EmployeeApi>() } returns employeeApi
every { employeeApi.method() } returns listEmployee

val resultList: List<Employee> = methodForTesting();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    相关资源
    最近更新 更多