Stub : qu’est-ce que c’est, types et utilisation en test

Auteur : IT Sectr Publié le : 2026-04-10 Temps de lecture : 9 min

Stub (bouchon, double de test) — un objet de test qui retourne des réponses prédéfinies aux appels de méthode au lieu d’une implémentation réelle. Dans le développement mobile, les stubs isolent le module testé des requêtes réseau, bases de données et systèmes de fichiers, permettant de vérifier la logique sans configuration d’environnement. Contrairement à mock, stub ne vérifie pas le comportement — il fournit seulement des données. Plus de détails dans l’article de Martin Fowler sur les test doubles.

Points clés

  • Stub — un double de test qui retourne des valeurs prédéfinies sur les appels de méthode sans logique
  • Isolation — les stubs désactivent les dépendances réelles : API, BD, fichiers, capteurs
  • Différence avec Mock — stub ne vérifie pas les appels, il remplace seulement la réponse
  • Android — MockWebServer (OkHttp) comme stub pour HTTP, MockK.constantAnswer pour Kotlin
  • iOS — OCMock et protocoles Swift avec implémentations de test comme stubs

Qu’est-ce qu’un Stub et en quoi diffère-t-il des autres test doubles ?

Stub est un objet double de test qui remplace une dépendance réelle dans un test et retourne des valeurs prédéfinies pour des appels spécifiques. Le terme a été introduit dans la classification de Gerard Meszaros (2007) dans le livre « xUnit Test Patterns ». Stub appartient à la catégorie des test doubles — des objets qui substituent des composants réels pendant les tests. L’objectif principal d’un stub est de fournir à l’unité testée des données prévisibles, en éliminant l’incertitude des systèmes externes.

Principe de fonctionnement — le test configure le stub avant l’exécution : « quand la méthode getUsers() sera appelée, retourne cette liste d’utilisateurs ». Stub ne contient pas de logique métier, ne vérifie pas l’ordre des appels et n’enregistre pas l’historique. Il se place simplement à la place du composant réel et retourne ce qu’on lui a dit. Dans le contexte des tests Android, cela signifie : le client OkHttp n’effectue pas de véritable requête au serveur, mais reçoit une réponse de MockWebServer configuré comme stub.

  • Stub — retourne des données, ne vérifie pas les appels
  • Mock — retourne des données et vérifie le comportement (verify)
  • Fake — implémentation simplifiée fonctionnelle avec logique réelle
  • Spy — enveloppe un objet réel, enregistrant les appels
  • Dummy — est passé mais n’est pas utilisé (null, objet vide)

Quand utiliser — les stubs sont optimaux pour tester la couche UI (ViewModel, Presenter) et la logique métier (UseCase, Interactor), où il faut vérifier la réaction à des données spécifiques : liste vide, serveur a retourné une erreur 500, token expiré. Tout cas où le test nécessite un état d’entrée spécifique est une tâche pour stub. Chaque scénario de test a sa propre configuration de stub, rendant les tests lisibles et prévisibles.

Classification des test doubles selon Meszaros

Gerard Meszaros (2007) dans le livre « xUnit Test Patterns » a identifié cinq types de test doubles : dummy, stub, spy, mock, fake. Chaque type résout son propre problème. Dummy — est passé mais pas utilisé. Stub — retourne des données. Spy — enregistre les appels. Mock — vérifie le comportement. Fake — contient une logique simplifiée. Comprendre cette classification aide le développeur à choisir le bon outil pour chaque scénario de test.

Où les stubs sont-ils utilisés dans les tests d’applications mobiles

Stubs pour les requêtes réseau

Requêtes réseau — le scénario le plus courant pour l’utilisation de stubs. L’application effectue des appels HTTP à l’API, et le test doit vérifier la réaction à différentes réponses : JSON réussi, erreur 401 (non autorisé), délai d’attente, tableau vide. MockWebServer (OkHttp) sur Android et URLProtocol (iOS) agissent comme des stubs, retournant des réponses HTTP prédéfinies sans connexion réelle au serveur. Cela accélère les tests de secondes en millisecondes.

Base de données — Room (Android) et CoreData (iOS) ont des variantes en mémoire, mais leur configuration prend encore du temps. Stub à la place du dépôt retourne des listes d’entités préparées sans toucher à la BD. C’est particulièrement efficace pour tester ViewModel, où il faut vérifier le tri, le filtrage ou la transformation des données. Le test s’exécute en millisecondes indépendamment du volume de données.

Services système — LocationManager, SensorManager, SharedPreferences nécessitent un appareil réel ou un émulateur. Stub pour LocationProvider retourne des coordonnées prédéfinies, pour SensorManager — des valeurs fixes d’accéléromètre. Sur iOS, l’équivalent est CLLocationManager avec une implémentation de délégué de test. Sans stubs, ces tests nécessitent un périphérique physique avec des conditions spécifiques.

Système de fichiers et cache — chargement d’images, mise en cache des réponses, travail avec les fichiers de configuration — toutes ces opérations dépendent de l’état du disque. Stub pour FileManager ou ImageCache retourne succès/erreur sans lire de fichiers réels. Cela élimine les échecs de test erronés dus aux divergences de chemins ou aux droits d’accès sur différentes machines de développement.

Stub vs Mock vs Fake : différences clés

Division des responsabilités — trois types de test doubles résolvent des tâches différentes. Stub : « donne-moi des données ». Mock : « vérifie que j’ai été appelé ». Fake : « je fonctionne comme le vrai, juste plus simplement ». La différence est cruciale pour la lisibilité des tests : si un test utilise mock là où il faut un stub, il est surchargé d’appels verify sans rapport avec le scénario testé.

CaractéristiqueStubMockFake
ObjectifFournir des donnéesVérifier l’interactionImplémentation simplifiée
LogiqueNonNonOui (mais simplifiée)
VérificationNonOui (verify)Indirecte (via état)
FlexibilitéFaible — réponses fixesMoyenneÉlevée — logique s’adapte
VitesseMaximaleÉlevéeMoyenne
ExempleMockWebServer retourne JSONMockito.verify(repository).save()InMemoryRepository avec HashMap

Règle pratique — si le test vérifie quelles données le composant testé a reçues — utilisez stub. Si le test vérifie si le composant a appelé la méthode de dépendance avec les bons arguments — utilisez mock. Si vous voulez simplement remplacer une BD par une table de hachage — c’est fake. Mélanger les types dans un même test le rend fragile : lors d’un changement d’implémentation, vous devrez réécrire à la fois la logique de stub et de verify.

Anti-patron : Stub avec verify

Stub avec verify — une erreur courante où le développeur configure un stub puis ajoute verify(stub).method(). Stub par définition ne doit pas être vérifié — pour cela il y a mock. Si vous devez vérifier qu’une méthode a été appelée avec des arguments spécifiques, utilisez Mockito.mock() au lieu de Mockito.stub(). Cette séparation maintient l’intention du test claire pour les autres développeurs.

Implémentation de stubs sur Android avec MockWebServer et MockK

MockWebServer — une bibliothèque OkHttp pour créer des stubs HTTP sur Android et JVM. Elle démarre un serveur HTTP local sur un port spécifié qui intercepte les requêtes du client OkHttp et retourne des réponses prédéfinies. La configuration prend trois lignes : créer le serveur, mettre en file d’attente la réponse, le démarrer. Le test peut mettre en file d’attente plusieurs réponses séquentiellement pour des scénarios avec pagination ou tentatives.

kotlin
class UserRepositoryTest {

    private val server = MockWebServer()

    fun setup() {
        server.start(8080)
        val client = OkHttpClient.Builder()
            .readTimeout(1, TimeUnit.SECONDS)
            .build()
    }

    fun test_user_list_success() {
        val json = "[{\"id\":1,\"name\":\"Alice\"}]"
        server.enqueue(MockResponse()
            .setBody(json)
            .setResponseCode(200)
        )
        val result = repository.getUsers()
        assertEquals(1, result.size)
    }

    fun teardown() {
        server.shutdown()
    }
}

MockK — une alternative à Mockito pour Kotlin avec un support de première classe pour les coroutines, les fonctions d’extension et les classes sealed. Les stubs dans MockK sont créés via coEvery (pour les fonctions suspend) et every (pour les fonctions régulières). Contrairement à MockWebServer, MockK stub des méthodes de dépendance individuelles plutôt que toute la couche HTTP. C’est pratique pour les tests unitaires de UseCase ou Interactor, où les dépendances sont des abstractions de dépôts.

kotlin
interface UserRepository {
    suspend fun getUsers(): List<User>
}

class GetUsersUseCaseTest {

    private val repo = mockk<UserRepository>()

    private val useCase = GetUsersUseCase(repo)

    fun test_empty_list() = runTest {
        coEvery { repo.getUsers() } returns emptyList()

        val result = useCase.invoke()

        assertTrue(result.isEmpty())
        coVerify(exactly = 1) { repo.getUsers() }
    }
}

Meilleure pratique — pour les tests d’intégration, utilisez MockWebServer (intercepte le vrai HTTP), pour les tests unitaires, utilisez MockK (stub les interfaces). Ne stubez pas ce que vous ne testez pas : si le test vérifie le Repository, ne stubez pas le client OkHttp à l’intérieur — utilisez un vrai MockWebServer au niveau HTTP. Cette règle maintient les tests pertinents et réduit la fragilité lors du refactoring.

Implémentation de stubs sur iOS avec OCMock et protocoles

Protocoles Swift comme stubs — dans l’approche native iOS, le stub est implémenté en substituant une structure de test qui se conforme au protocole de la dépendance. Au lieu d’un NetworkService réel, le test reçoit un StubNetworkService qui retourne des données fixes. Swift est un langage à typage statique, donc le stub doit se conformer au même protocole que le service réel. Le compilateur garantit que le stub implémente toutes les méthodes requises.

swift
protocol NetworkServiceProtocol {
    func fetchUsers() async throws -> [User]
}

struct StubNetworkService: NetworkServiceProtocol {
    let result: Result<[User], Error>

    func fetchUsers() async throws -> [User] {
        try result.get()
    }
}

final class UsersViewModelTests: XCTestCase {
    func test_success_state() async {
        let stub = StubNetworkService(
            result: .success([User(name: "Alice")])
        )
        let vm = UsersViewModel(service: stub)
        await vm.load()
        XCTAssertEqual(vm.users.count, 1)
    }
}

OCMock pour Objective-C — une bibliothèque pour créer des stubs et des mocks dans les projets iOS legacy. OCMock prend en charge les méthodes stub avec des arguments et des valeurs de retour. Les projets modernes en Swift préfèrent une approche basée sur les protocoles avec des stubs manuels — cela donne le contrôle sur chaque méthode et ne nécessite pas de dépendances externes. OCMock reste une option pour les projets où la protocollisation de toutes les dépendances n’est pas économiquement viable.

URLProtocol pour les stubs HTTP — un mécanisme système dans iOS pour intercepter les requêtes réseau via une sous-classe de URLProtocol. Le test enregistre un URLProtocol personnalisé qui intercepte URLSession et retourne des réponses stub. L’avantage par rapport aux stubs manuels : vous n’avez pas besoin de modifier l’architecture de l’application — URLSession reste réel, mais les données sont substituées au niveau du protocole. L’inconvénient : plus difficile à déboguer qu’un service stub explicite.

Foire aux questions

En quoi Stub diffère-t-il de Mock ?

Stub retourne des données prédéfinies et ne vérifie pas si un appel a eu lieu. Mock vérifie en plus que la méthode a été appelée avec les bons arguments (verify). Stub répond à la question « que retourner », Mock répond à « l’appel a-t-il été fait ». Utilisez stub pour la vérification d’état, mock pour la vérification d’interaction.

Quand utiliser Fake au lieu de Stub ?

Fake est nécessaire quand le test nécessite une implémentation fonctionnelle (même simplifiée) — par exemple, une base de données en mémoire au lieu de Room. Stub convient pour des scénarios uniques avec des données prédéfinies. Si vous répétez le même stub dans 10 tests — vous avez probablement besoin d’un Fake. Fake réduit la duplication parce que la logique vit dans une seule classe.

Peut-on stubber des méthodes statiques ?

Sur Android — MockK pour les objets Kotlin (object) prend en charge mockkObject(), y compris les méthodes statiques des classes Java via mockkStatic(). Sur iOS — les méthodes statiques Swift ne peuvent pas être stubées directement ; utilisez des protocoles et DI pour remplacer un appel static par une méthode d’instance d’un protocole. Les stubs statiques sont de la dette technique et doivent être évités dans le nouveau code.

Comment stubber des requêtes réseau sur Android ?

Utilisez MockWebServer (OkHttp) — il fonctionne comme un serveur HTTP local qui met en file d’attente les réponses. Pour Retrofit, remplacez simplement l’URL de base par localhost:8080. Pour Ktor, utilisez MockEngine — un mécanisme intégré pour substituer HttpStatement. Les deux approches fonctionnent sans internet réel et donnent un contrôle total sur le code de statut, le corps et les en-têtes de la réponse.

Stub vs Spy — quelle est la différence ?

Spy enveloppe un objet réel et enregistre les appels, tandis que Stub remplace complètement l’objet par des réponses fixes. Spy permet une utilisation partielle de l’implémentation réelle (les autres méthodes fonctionnent telles quelles), alors que stub non. Si vous devez vérifier qu’une méthode a été appelée mais qu’une partie de la logique doit être exécutée — utilisez spy, pas stub.

Résumé

  • Stub — un double de test qui retourne des réponses prédéfinies aux appels de méthode pendant les tests
  • Isolation des dépendances — les stubs remplacent les requêtes réseau, BD, services système et système de fichiers
  • Différence avec Mock — stub ne vérifie pas les appels, il retourne seulement des données sans vérification de comportement
  • Outils Android — MockWebServer pour HTTP, MockK pour les interfaces Kotlin avec support des coroutines
  • Outils iOS — stubs basés sur les protocoles en Swift, URLProtocol pour HTTP, OCMock pour Objective-C
  • Ne mélangez pas les rôles — n’ajoutez pas verify à stub, utilisez mock pour la vérification des appels
  • Stub + MockWebServer — approche standard pour les tests d’intégration sans serveur réel

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi