Mocks et fixtures en Rust : comment tester du code sans douleur

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi les tests en Rust ne sont pas ennuyeux



Si vous avez déjà écrit des tests pour du code en Python ou JavaScript, vous avez sûrement rencontré cette situation : votre méthode appelle une API externe, lit un fichier sur le disque ou accède à une base de données. Exécuter ces tests dans un environnement réel est une douleur. Ils sont lents, peu fiables (et si l'API tombe ?) et nécessitent une configuration de l'environnement.



En Rust, la situation n'est pas différente. Seulement, Rust est un langage système, et ici les tests doivent être rapides, fiables et déterministes. C'est exactement pour cela que les objets mock et les fixtures sont nécessaires.



Dans cet article, nous allons voir comment écrire des tests en Rust qui ne dépendent pas du monde extérieur. Vous apprendrez à remplacer les dépendances, à préparer les données pour les tests et à le faire de manière élégante. C'est parti !



Que sont les objets mock et les fixtures ?



Objets Mock (mocks)

Un objet mock est une imitation d'un composant réel du système. Vous créez un objet qui se comporte comme vous le souhaitez pour le test : il retourne des valeurs définies, génère des erreurs ou vérifie que ses méthodes ont été appelées avec les bons arguments.



Imaginez que vous ayez un service d'envoi d'email. Dans le test, vous ne voulez pas réellement envoyer des emails - vous utilisez un mock qui vérifie simplement que le service a été appelé avec la bonne adresse et le bon texte.



Fixtures

Les fixtures sont des données ou un état préparés, nécessaires à l'exécution du test. Par exemple, une base de données de test, un fichier de configuration, des structures préétablies. En Rust, les fixtures sont souvent implémentées via des fonctions ordinaires qui retournent des objets prêts à l'emploi.



Ensemble, les mocks et les fixtures vous donnent un contrôle total sur l'environnement du test. Vous testez uniquement votre logique, et non le fonctionnement des services externes.



Principes de base des tests en Rust



Avant de plonger dans les mocks, rappelons comment sont structurés les tests en Rust. Un test unitaire typique ressemble à ceci :



#[cfg(test)]mod tests {    use super::*;

#[test] fn test_addition() { assert_eq!(2 + 2, 4); }}


Tout est simple. Mais lorsque votre code commence à dépendre de ressources externes (fichiers, requêtes HTTP, bases de données), des problèmes apparaissent. La solution est d'inverser les dépendances et d'utiliser le modèle Dependency Injection (injection de dépendances).



Exemple pratique : un service de chargement de données



Supposons que nous ayons une structure DataLoader qui charge des données depuis une API externe et les traite. Nous voulons tester le traitement sans appeler l'API réelle.



D'abord, définissons un trait (interface) pour la source de données :



pub trait DataSource {    fn fetch_data(&self) -> Result<String, String>;}


Maintenant, implémentons une source réelle qui effectue une requête HTTP (simplifiée) :



pub struct RealDataSource {    pub url: String,}

impl DataSource for RealDataSource { fn fetch_data(&self) -> Result<String, String> { // Ici, il y aurait une vraie requête HTTP Ok(format!("Données depuis {}", self.url)) }}


Et le service qui utilise cette source :



pub struct DataLoader<T: DataSource> {    source: T,}

impl<T: DataSource> DataLoader<T> { pub fn new(source: T) -> Self { DataLoader { source } }

pub fn load_and_process(&self) -> Result<String, String> { let raw_data = self.source.fetch_data()?; // Un traitement quelconque Ok(format!("Traité : {}", raw_data)) }}


Notez que DataLoader ne dépend pas d'une implémentation spécifique de DataSource. Il fonctionne avec n'importe quel type implémentant ce trait. C'est la clé de la testabilité.



Créer un objet mock manuellement



La manière la plus simple est de créer une structure de test

Blogs

Book Recommendations