Simulaciones

Mockall es una biblioteca que se usa para hacer simulaciones. Debes refactorizar tu código para usar traits, con los que podrás hacer simulaciones:

use std::time::Duration;

#[mockall::automock]
pub trait Pet {
    fn is_hungry(&self, since_last_meal: Duration) -> bool;
}

#[test]
fn test_robot_dog() {
    let mut mock_dog = MockPet::new();
    mock_dog.expect_is_hungry().return_const(true);
    assert_eq!(mock_dog.is_hungry(Duration::from_secs(10)), true);
}
This slide should take about 5 minutes.
  • Estos consejos son útiles para Android (AOSP), donde Mockall es la biblioteca de simulaciones recomendada. Hay otras bibliotecas de simulación disponibles en crates.io, especialmente en el área de servicios de simulación de HTTP. Las demás bibliotecas de simulación funcionan de forma similar a Mockall, lo que significa que facilitan la obtención de una implementación simulada de un trait determinado.

  • Ten en cuenta que las simulaciones son algo polémicas, ya que te permiten aislar por completo una prueba de sus dependencias. El resultado inmediato es una ejecución de pruebas más rápida y estable. Por otro lado, las simulaciones se pueden configurar de forma incorrecta y devuelven un resultado diferente del que se obtendría con las dependencias reales.

    Si es posible, te recomendamos que uses las dependencias reales. Por ejemplo, muchas bases de datos te permiten configurar un backend en la memoria. Es decir, en tus pruebas obtendrás el comportamiento correcto y, además, son rápidas y se limpiarán de forma automática tras las pruebas.

    Del mismo modo, muchos frameworks web te permiten iniciar un servidor en proceso que se vincula a un puerto aleatorio en localhost. Siempre es mejor utilizar esta opción en lugar de simular el framework, ya que te ayuda a hacer pruebas con el código en el entorno real.

  • Mockall no forma parte de Rust Playground, por lo que debes ejecutar este ejemplo en un entorno local. Usa cargo add modelall para añadir de forma rápida Mockall a un proyecto de Cargo.

  • Mockall tiene muchas más funciones. En concreto, puedes configurar expectativas en función de los argumentos. Aquí utilizamos el ejemplo para simular un gato que tiene hambre 3 horas después de que le hayan dado de comer:

#[test]
fn test_robot_cat() {
    let mut mock_cat = MockPet::new();
    mock_cat
        .expect_is_hungry()
        .with(mockall::predicate::gt(Duration::from_secs(3 * 3600)))
        .return_const(true);
    mock_cat.expect_is_hungry().return_const(false);
    assert_eq!(mock_cat.is_hungry(Duration::from_secs(1 * 3600)), false);
    assert_eq!(mock_cat.is_hungry(Duration::from_secs(5 * 3600)), true);
}
  • Puedes utilizar .times(n) para limitar el número de veces que se puede llamar a un método de simulación a n. Si no se cumple, la simulación activará un pánico automáticamente cuando se elimine.