¿Cómo simular el ApplicationContext en el objeto compañero en Kotlin?
Ayuda a probar una función que llama a un método de clase.
Hay una clase cuyo campo se inicializa con una cadena de métodos appContext().getBean().
class ClassA {
private val employeeApi: EmployeeApi = appContext().getBean()
fun execute(): List<employee> {
return employeeApi.method()
}
}
y por ejemplo hay una función para llamar a los métodos de clase.
fun methodForTesting(params: ClassA.() -> Unit): List<employee> {
return ClassA().apply(params).execute()
}
Esta función necesita ser probada. ¿Cómo hacerlo?
- Abrir acceso al método en el archivo utilizando
mockkStatic("com.company.MyFile")
- Crear una lista de empleados que deben ser devueltos
- Crear un método stub
- Llamar al método
- Verificar los datos
@Test
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)
}
Si escribo así, entonces ocurre un error. ¿Cómo se puede finalizar la solución?
Error:
kotlin.UninitializedPropertyAccessException: lateinit property FIELD has not been initialized
at Mockito.when
(classA.execute()).thenReturn(listEmployee) <– HERE
“`kotlin
@Configuration
@EnableConfigurationProperties(HurmaProperties::class)
class AppConfig : ApplicationContextAware {
private var applicationContext: ApplicationContext? = null
<pre><code>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
}
</code></pre>
}
fun appContext() = AppConfig.appCtx
“`
davy.ai
Para probar el método
methodForTesting()
, podemos usar el framework MockK para simular la claseClassA
y su métodoexecute()
. Aquí está la solución para finalizar el caso de prueba anterior:La solución hace lo siguiente:
EmployeeApi
usando MockK y asumimos que se asigna al campoemployeeApi
deClassA
.every { ... } returns ...
de MockK se utiliza para simular el comportamiento deemployeeApi.method()
, que devuelve una lista de empleados. Esto se usará más adelante en la prueba.appContext().getBean<employeeapi>()
que es llamada porClassA
. Esto se hace utilizando la funciónmockkStatic()
.ClassA
llamando amethodForTesting()
conClassA::execute
como parámetro.assertThat()
de AssertJ para verificar que la lista devuelta pormethodForTesting()
es igual a la lista de empleados devuelta poremployeeApi.method()
.Nota: asumimos que
EmployeeApi
es una interfaz porque llamar al mismo método en una instancia simulada de una clase concreta puede no producir el resultado deseado.