Funciones Falsas
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
En programación funcional, nuestras dependencias tienden menos a ser instancias de clases concretas y más a ser funciones. Cuando realizamos pruebas unitarias de algo con dependencias funcionales, normalmente es más sencillo pasar otra función que simular esa dependencia. Consideremos, por ejemplo, la siguiente implementación:
fun interface HasAnswer {
fun answer(question: String): Int
}
class AnsweringService: HasAnswer {
override fun answer(question: String): Int { TODO() }
}
class MyService(private val hasAnswer: HasAnswer) {
fun respond(question: String): Int = hasAnswer.answer(question)
}
Tradicionalmente, simularíamos HasAnswer y pasaríamos ese mock a MyService:
val mockHasAnswer = run {
val ret = mockk<HasAnswer>()
every { ret.answer(any()) } returns 42
ret
}
val myService = MyService(mockHasAnswer)
// tests here
Sin embargo, también podemos pasar simplemente una lambda, que resulta mucho más sencillo:
val myService = MyService(hasAnswer = { 42 })
// tests to follow
Si queremos que esta función de doble de prueba devuelva valores diferentes y/o lance excepciones, kotest ofrece funciones auxiliares simples que facilitan estas tareas, como:
val fakeFunction = sequenceOf("yes", "no", "maybe").toFunction()
fakeFunction.next() shouldBe "yes"
fakeFunction.next() shouldBe "no"
fakeFunction.next() shouldBe "maybe"
Esta función falsa puede usarse en pruebas unitarias de la siguiente manera:
val fakeFunction = sequenceOf("yes", "no", "maybe").toFunction()
val myService = MyService { fakeFunction.next() }
myService.respond("what") shouldBe "yes"
myService.respond("when") shouldBe "no"
myService.respond("where") shouldBe "maybe"
Si necesitáramos una función falsa que a veces devuelva un valor y a veces lance una excepción, puede hacerse fácilmente así:
val fakeFunction = sequenceOf(
Result.success("yes"),
Result.failure(RuntimeException("bad request")),
Result.success("no")
).toFunction()
fakeFunction.next() shouldBe "yes"
shouldThrow<RuntimeException> { fakeFunction.next() }
fakeFunction.next() shouldBe "no"
Dado que esta función implementa la interfaz HasAnswer, también podemos usarla como dependencia en nuestras pruebas unitarias.