Testing de clases con dependencias externas usando fakes

Clase 6 de 16Curso de Android Testing

Resumen

Para asegurar calidad y rapidez en las pruebas de desarrollo es importante controlar las dependencias externas de nuestra aplicación. Una técnica efectiva para lograrlo es el uso de test doubles como fakes, que permiten simular comportamientos externos como APIs sin necesidad de hacer llamadas reales a servicios externos. Esto no sólo agiliza las pruebas, sino que también nos brinda control absoluto sobre los escenarios que queremos evaluar.

¿Qué es un fake y por qué utilizarlo en pruebas?

Un fake es una implementación controlada y simplificada de una dependencia externa, como por ejemplo una API, usado específicamente en pruebas unitarias. Tanto si la dependencia tiene éxito como si genera errores, el fake posibilita definir explícitamente qué devuelve cada método o cuándo lanzar excepciones.

  • Controla los escenarios de prueba de forma precisa.
  • Evita llamadas que requieren red o servicios externos reales.
  • Acelera el proceso de las pruebas al usar solo código local.

¿Cómo crear un fake API implementando una clase en Kotlin?

Crear un fake es sencillo con Kotlin. Debe imitar la firma de la clase real que se quiere suplantar, permitiendo así ser fácilmente intercambiable en pruebas.

  1. Define los datos simulados:
val users = (1..10).map { User(it.toString(), "user$it") }
val places = (1..10).map { Place(UUID.randomUUID().toString(), "place$it", coordinates) }
  1. Implementa métodos que repliquen la funcionalidad esperada:
fun getUser(userId: String): User {
    return users.find { it.id == userId } ?: throw Exception("user not found")
}

Con esto generas una estructura similar a la API real.

¿Cómo testear una clase que usa fakes como dependencia?

Una vez definido el fake, integrarlo en pruebas del usuario repository implementation es simple usando un método setup adecuado.

  • Inicializa el fake y la clase que lo usa:
@Before
fun setup() {
    api = UserFakeApi()
    repository = UserRepository(api)
}
  • Implementa tus pruebas:
@Test
fun `given valid userID when getProfile with fakeAPI then returns profile`() = runTest {
    val userId = "1"
    val result = repository.getProfile(userId)
    assertThat(result.isSuccess).isTrue()
    assertThat(result.getOrNull()?.user?.id).isEqualTo(userId)
}

Esto permite verificar rápidamente el manejo correcto de datos y errores.

¿Qué ventajas ofrecen los fakes frente a las implementaciones reales en tests?

Usar fakes garantiza que las pruebas sean independientes y rápidas porque no dependen de factores externos como bases de datos reales o sistemas externos. Esto facilita que las pruebas:

  • Sean consistentes y repetibles.
  • No dependan de disponibilidad externa.
  • Hagan más eficiente todo el proceso de desarrollo.

¿Tienes alguna experiencia usando fakes para facilitar el testing en tu desarrollo? Comenta tu caso y cómo esta técnica ha contribuido a mejorar tus procesos de desarrollo.