{ }
type
GraphQL · Mocking · Testing · MSW · Apollo
GraphQL Mocking für Frontend- und API-Tests
Schema, MSW und MockedProvider richtig einsetzen

Ohne Mocking blockiert ein nicht fertiger Backend-Endpoint die gesamte Frontend-Entwicklung. GraphQL-Mocking auf Schema-Ebene macht Frontend-Teams unabhängig, ermöglicht Fehlerszenario-Tests und beschleunigt den Entwicklungszyklus erheblich.

15 Min. Lesezeit MSW · Apollo MockedProvider · Schema Mocking · Magento React · TypeScript · Vitest · Playwright

1. Warum GraphQL-Mocking mehr ist als Dummy-Daten

Der naheliegendste Ansatz im Frontend: eine JavaScript-Datei mit hartcodierten Testdaten anlegen und in Komponenten-Props einsetzen. Das funktioniert für einzelne Unit-Tests, versagt aber sobald eine Komponente selbst eine GraphQL-Query absetzt, sobald Netzwerk-Ladezeiten simuliert werden sollen oder sobald Fehlerpfade getestet werden müssen. Echter GraphQL-Mocking operiert auf der Ebene des Netzwerk-Handlers oder des GraphQL-Clients und fängt Queries genau so ab, wie es der echte Server täte.

Die Vorteile gehen weit über Isolation hinaus. Ein guter Mock simuliert auch langsame Netzwerke, Authentifizierungsfehler, partielle Datenfehler innerhalb einer Response und Timeout-Verhalten. Wer nur mit statischen Fixture-Dateien arbeitet, bekommt zuverlässige Tests für den Erfolgsfall – aber keine Confidence für die Fälle, die in Produktion am häufigsten zu Supporttickets führen. GraphQL-Mocking auf Schema-Basis stellt außerdem sicher, dass gemockte Daten immer schema-konform sind – ein Mock, der nicht zum Schema passt, scheitert früh im Entwicklungsprozess, nicht in Produktion.

2. Schema-basiertes Mocking: addMocksToSchema

Der Einstieg in schema-basiertes GraphQL-Mocking beginnt mit dem Paket @graphql-tools/mock. Die Funktion addMocksToSchema nimmt ein bestehendes Schema-Objekt und ergänzt jeden Resolver automatisch mit realistischen Standardwerten: Strings werden als leere Strings gemockt, Integers als 42, Booleans als false. Für produktiv einsetzbare Tests überschreibt man diese Defaults mit eigenen Mock-Resolvern pro Typ und Feld. Das Schema selbst wird entweder aus der SDL geladen oder per Introspection vom echten Endpoint bezogen.

Der entscheidende Vorteil dieses Ansatzes: die Mock-Antworten werden durch den vollständigen GraphQL-Execution-Stack verarbeitet. Das bedeutet, dass Validierung, Typprüfung und Feld-Auflösung genauso ablaufen wie beim echten Server. Gibt ein Client eine Query ab, die nicht zum Schema passt, schlägt sie auch gegen den Mock fehl – was Fehler, die sonst erst bei echten API-Calls auftauchen, in die lokale Entwicklungszeit verlagert. Für Teams, die Schema-First arbeiten, ist das der bevorzugte Ansatz: Schema festschreiben, Mock-Server aufsetzen, Frontend-Entwicklung starten – ohne auf Backend-Implementierung zu warten.


# Mock-Schema für einen Produktkatalog (Schema-First-Ansatz)
# Dieses Schema wird von addMocksToSchema genutzt

type Query {
  product(sku: String!): Product
  products(search: String, pageSize: Int): ProductList!
  cart(cartId: String!): Cart
}

type Product {
  sku: String!
  name: String!
  price_range: PriceRange!
  stock_status: StockStatus!
  description: String
}

type ProductList {
  items: [Product!]!
  total_count: Int!
}

type PriceRange {
  minimum_price: Price!
}

type Price {
  final_price: Money!
}

type Money {
  value: Float!
  currency: String!
}

type Cart {
  id: String!
  items: [CartItem!]!
  prices: CartPrices!
}

type CartItem {
  uid: String!
  quantity: Int!
  product: Product!
}

type CartPrices {
  grand_total: Money!
}

enum StockStatus {
  IN_STOCK
  OUT_OF_STOCK
}

3. MSW im Browser: Queries ohne echten Server

Mock Service Worker (MSW) ist der bevorzugte Ansatz für Browser-basiertes GraphQL-Mocking, weil er auf der Service-Worker-API des Browsers operiert und damit echte Netzwerkanfragen abfängt. Das Frontend-Code-Verhalten ändert sich dabei gar nicht – es sendet echte Fetch-Requests, die MSW interceptiert und mit konfigurierten Responses beantwortet. Im Gegensatz zu Monkey-Patching von fetch oder Axios-Adaptern funktioniert MSW mit jeder HTTP-Bibliothek und auch in Playwright-E2E-Tests.

Für GraphQL-Queries bietet MSW den graphql.query() und graphql.mutation() Handler. Der Handler matcht über den Operation-Namen, nicht über die URL allein – was es einfach macht, mehrere Endpoints mit unterschiedlichen Responses zu konfigurieren. In Entwicklungsumgebungen aktiviert man MSW per Service-Worker-Registration im Browser; in Vitest oder Jest läuft MSW über Node-Interceptors ohne Service-Worker. Derselbe Handler-Code funktioniert damit in allen Testebenen, was Konsistenz zwischen Unit-, Integrations- und E2E-Tests sicherstellt.


# Abgefangene Query: MSW matcht über den Operation-Namen "GetProduct"
# Der Handler in handlers.ts gibt diese Struktur als Response zurück

query GetProduct($sku: String!) {
  product(sku: $sku) {
    sku
    name
    price_range {
      minimum_price {
        final_price {
          value
          currency
        }
      }
    }
    stock_status
    description
  }
}

# Fehlerfall-Query: gleiche Operation, MSW-Handler gibt errors[] zurück
# Testet die Fehlerbehandlung im Frontend ohne Serveränderung
query GetProductError($sku: String!) {
  product(sku: $sku) {
    sku
    name
  }
}

4. Apollo MockedProvider für Komponententests

Wer Apollo Client im React-Frontend einsetzt, bekommt mit MockedProvider eine direkte Mocking-Lösung für Komponenten-Tests. Der MockedProvider ersetzt den echten Apollo-Client in der Test-Rendertree und antwortet auf definierte Queries mit vorbereiteten Antworten. Die Konfiguration erfolgt über ein Array von MockedResponse-Objekten, die jeweils eine Query-Operation und die gewünschte Antwort oder einen Fehler enthalten.

Ein häufiger Fallstrick beim Apollo MockedProvider: Queries müssen exakt übereinstimmen, inklusive Variablen. Stimmt die im Test verwendete Query nicht bitgenau mit der in der Komponente überein – zum Beispiel wegen unterschiedlicher Fragment-Definitionen oder Variablen-Defaults – liefert der MockedProvider keine Antwort und der Test schlägt mit einem Timeout-Fehler fehl. Deshalb empfiehlt sich die Praxis, GraphQL-Documents als .graphql-Dateien zu definieren, die sowohl in Produktionscode als auch in Tests importiert werden. Zusätzlich bietet der addTypename: false-Parameter des MockedProviders eine Vereinfachung für Tests, die keine __typename-Felder benötigen.

5. Fehlerszenarien und partielle Fehler mocken

GraphQL-Fehler haben eine besondere Struktur: Anders als HTTP-Fehler können GraphQL-Responses gleichzeitig Daten und Fehler enthalten. Ein partieller Fehler tritt auf, wenn ein Resolver für ein optionales Feld fehlschlägt, während andere Felder korrekt befüllt werden. Das Frontend muss in diesem Fall entscheiden, ob und wie die partiellen Daten angezeigt werden. Dieses Szenario ist mit statischen Fixture-Daten kaum testbar – ein gutes Mock-Setup ermöglicht es, solche Responses gezielt zu erzeugen.

Mit MSW gibt man im Response-Objekt sowohl data als auch errors zurück, um partielle Fehler zu simulieren. Im Apollo MockedProvider nutzt man das error-Property eines MockedResponse für Netzwerkfehler und das result.errors-Array für GraphQL-Fehler innerhalb einer erfolgreichen HTTP-Response. Wer diese Unterscheidung in Tests nicht abbildet, bekommt keine Aussage darüber, ob das Frontend korrekt auf das Error-Boundary-Verhalten von Apollo reagiert oder ob ein Ladeindikator hängen bleibt, wenn ein Resolver still fehlschlägt.


# Partieller Fehler: cart wird korrekt zurückgegeben,
# aber das Feld "shipping_addresses" schlägt im Resolver fehl.
# MSW-Handler gibt diese Struktur zurück, um Frontend-Verhalten zu testen.

# Erwartete Response-Struktur (JSON):
# {
#   "data": {
#     "cart": {
#       "id": "abc123",
#       "items": [...],
#       "prices": { "grand_total": { "value": 89.99, "currency": "EUR" } },
#       "shipping_addresses": null
#     }
#   },
#   "errors": [
#     {
#       "message": "Shipping address resolver failed",
#       "path": ["cart", "shipping_addresses"],
#       "extensions": { "category": "graphql-authorization" }
#     }
#   ]
# }

query GetCart($cartId: String!) {
  cart(cartId: $cartId) {
    id
    items {
      uid
      quantity
      product { sku name }
    }
    prices {
      grand_total { value currency }
    }
    shipping_addresses {
      city
      postcode
    }
  }
}

6. Mocking für Magento-GraphQL-Endpoints

Bei Magento GraphQL kommen einige spezifische Herausforderungen hinzu, die das Mocking komplexer machen. Magento-Queries laufen gegen einen einzelnen Endpoint (/graphql), nutzen aber store-spezifische Header wie Store: de und optionale Authentifizierungs-Bearer-Tokens für Kundenkontext. MSW-Handler können diese Header auswerten und unterschiedliche Mock-Responses für Gast- und Kundensitzungen liefern. Das ist besonders wertvoll beim Testen von Headless-Frontends, die Warenkorb, Checkout und Kundenkonto über GraphQL abwickeln.

Ein weiterer Magento-spezifischer Aspekt: viele produktive Magento-GraphQL-Queries nutzen Inline-Fragmente auf Union-Typen wie ProductInterface, um zwischen SimpleProduct, ConfigurableProduct und anderen Produkttypen zu unterscheiden. Im Mock muss das __resolveType-Feld korrekt gesetzt werden, damit der GraphQL-Execution-Stack weiß, welchen konkreten Typ er auflösen soll. Schema-basiertes Mocking mit addMocksToSchema löst das automatisch, sofern der Mock-Resolver für ProductInterface einen konkreten Typ zurückgibt.


# Magento-typische Query mit Union-Typ-Inline-Fragmenten
# Muss im Mock __resolveType korrekt zurückgeben

query GetProductDetails($sku: String!) {
  products(filter: { sku: { eq: $sku } }) {
    items {
      __typename
      sku
      name
      price_range {
        minimum_price {
          final_price { value currency }
        }
      }
      ... on ConfigurableProduct {
        configurable_options {
          attribute_code
          label
          values { uid label swatch_data { value } }
        }
        variants {
          product { sku name }
          attributes { uid label code value_index }
        }
      }
      ... on SimpleProduct {
        stock_status
        only_x_left_in_stock
      }
    }
  }
}

7. Contract-Tests zwischen Mock und echtem Schema

Contract-Tests schließen die gefährliche Lücke zwischen Mocks und Realität: Sie stellen sicher, dass das gemockte Schema mit dem echten Produktions-Schema übereinstimmt. Ohne Contract-Tests können Mocks veralten – eine Mutation bekommt neue Pflichtfelder, ein Typ wird umbenannt, ein Feld erhält einen anderen Rückgabetyp. Der Mock-basierte Komponententest läuft weiter grün, während der Produktionscode bricht.

Das Werkzeug der Wahl ist GraphQL Inspector, das zwei Schemata vergleicht und Breaking Changes identifiziert. Im CI-Prozess lädt ein Job das aktuelle Schema vom Produktions-Endpoint via Introspection und vergleicht es mit dem Schema, auf dem die Mock-Handler basieren. Gibt es Abweichungen, schlägt der CI-Build fehl, bevor der Code in Produktion geht. Für Magento-Projekte empfiehlt sich zusätzlich das Speichern des Schema-Snapshots im Repository, damit auch ohne Netzwerkzugang zum Produktiv-System Schema-Diffs erkannt werden können.

8. Mocking-Strategien im Vergleich

Unterschiedliche Testebenen erfordern unterschiedliche GraphQL-Mocking-Strategien. Die Wahl des richtigen Ansatzes hängt vom Testziel, dem eingesetzten GraphQL-Client und der gewünschten Isolation ab.

Strategie Einsatzgebiet Vorteil Grenze
addMocksToSchema Lokaler Mock-Server, Storybook Schema-validiert, alle Typen automatisch Kein Netzwerk-Intercepting
MSW (graphql.query) Unit-, Integration-, E2E-Tests Echter Netzwerk-Stack, client-agnostisch Kein Schema-Validation per default
Apollo MockedProvider React-Komponenten-Tests Exakte Query-Kontrolle, Cache-State Apollo-spezifisch, exaktes Match nötig
Fixtures (JSON) Einfache Unit-Tests, Snapshots Schnell, kein Setup nötig Kein Fehlerszenario, veraltet schnell
Contract-Tests (Inspector) CI-Pipeline, Schema-Drift-Erkennung Verhindert Mock-Realitäts-Drift Erfordert Schema-Zugriff im CI

In der Praxis kombiniert man mehrere Strategien: addMocksToSchema für den lokalen Entwicklungsserver und Storybook, MSW für Vitest- und Playwright-Tests und Apollo MockedProvider für isolierte Komponenten-Tests. Die Contract-Tests laufen einmal täglich in der CI-Pipeline und schlagen bei Schema-Drift Alarm, bevor ein neues Frontend-Release deployed wird.

9. Zusammenfassung

Effektives GraphQL-Mocking für Frontend- und API-Tests erfordert mehr als statische Fixture-Dateien. Schema-basiertes Mocking mit addMocksToSchema stellt sicher, dass Mock-Responses immer schema-konform sind. MSW ermöglicht echtes Netzwerk-Intercepting, das in Unit-, Integrations- und E2E-Tests konsistent funktioniert. Apollo MockedProvider gibt volle Kontrolle über Apollo-Cache-State und Query-Matching in Komponenten-Tests. Die Kombination dieser Strategien reduziert fluktuierende Tests, deckt Fehlerpfade ab und macht Frontend-Teams unabhängig von Backend-Entwicklungsstand.

Contract-Tests zwischen Mock-Schema und Produktions-Schema sind der entscheidende Schutz gegen den häufigsten Langzeitfehler: Mocks, die grün bleiben, während das echte Schema längst weiterentwickelt wurde. Mit GraphQL Inspector im CI-Prozess wird dieser Drift automatisch erkannt, bevor er zu Produktionsproblemen wird.

GraphQL Mocking für Frontend- und API-Tests — Das Wichtigste auf einen Blick

Schema-Mocking

addMocksToSchema validiert Mock-Responses gegen das echte Schema – verhindert Mock-Drift in der lokalen Entwicklung und in Storybook.

MSW für alle Testebenen

Mock Service Worker interceptiert echte Netzwerkanfragen, funktioniert client-agnostisch und konsistent in Unit-, Integrations- und E2E-Tests.

Fehlerpfade

Partielle GraphQL-Fehler (data + errors) gezielt mocken – testet Fehlerbehandlung, Ladeindikator-Verhalten und Error-Boundaries im Frontend.

Contract-Tests

GraphQL Inspector im CI vergleicht Mock-Schema mit Produktions-Schema – schlägt Alarm bei Breaking Changes, bevor sie in Produktion gelangen.

11. FAQ: GraphQL Mocking für Frontend- und API-Tests

1MSW vs. Apollo MockedProvider?
MSW interceptiert echte Netzwerkanfragen, ist client-agnostisch und funktioniert in Unit-, Integrations- und E2E-Tests. Apollo MockedProvider ist Apollo-spezifisch, bietet aber direkte Cache-Kontrolle und ist ideal für isolierte Komponenten-Tests.
2Wie verhindert man Mock-Drift?
GraphQL Inspector im CI vergleicht Mock-Schema mit dem Produktions-Schema. Schema-First-Entwicklung stellt sicher, dass Mocks direkt aus der SDL erstellt werden und automatisch aktuell bleiben.
3MSW in Playwright-E2E-Tests?
Ja. Dieselben MSW-Handler funktionieren in Vitest (Node-Interceptor) und Playwright (Service Worker im Browser). Eine einzige Handler-Datei für alle Testebenen.
4Partielle GraphQL-Fehler mocken?
GraphQL-Responses können gleichzeitig data und errors enthalten. MSW gibt beides im Response-Objekt zurück. Apollo MockedProvider unterscheidet zwischen result.errors (GraphQL-Fehler) und error (Netzwerkfehler).
5Apollo MockedProvider Timeout-Fehler?
Meist ein Query-Mismatch. Die Query in der Komponente muss bitgenau mit der im Mock übereinstimmen. GraphQL-Documents als .graphql-Dateien teilen statt duplizieren.
6Magento-Authentifizierung in Tests mocken?
MSW-Handler werten den Authorization-Header aus und liefern unterschiedliche Responses für Gäste und Kunden. Login-Flows, Warenkorb-Zustand und Kundenpreise ohne echten Magento-Server testbar.
7addMocksToSchema typsicher in TypeScript?
Ja, in Kombination mit GraphQL Code Generator. Generierte TypeScript-Typen für Mock-Resolver nutzen – Mock-Daten werden zur Compile-Zeit geprüft.
8Magento Union-Typen mocken?
addMocksToSchema löst Union-Typen automatisch, wenn der Mock-Resolver einen konkreten Typ zurückgibt. __resolveType entscheidet zwischen SimpleProduct und ConfigurableProduct.
9Gleichen Mock in Storybook und Tests nutzen?
Mit MSW und dem Storybook-Addon. Dieselben Handler-Definitionen in Storybook und Tests – eine einzige Quelle der Wahrheit für Mock-Daten.
10Ladezeiten und Timeouts testen?
MSW-Handler verzögern Antworten mit delay() oder geben gar keine zurück. Damit lassen sich Skeleton-Loader, Error-Boundaries und Retry-Logik zuverlässig testen.