Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| de:modul:ffit:3-jahr:cicd:learningunits:lu06:a [2026/03/15 17:11] – apeter | de:modul:ffit:3-jahr:cicd:learningunits:lu06:a [2026/03/15 18:28] (aktuell) – apeter | ||
|---|---|---|---|
| Zeile 2: | Zeile 2: | ||
| Test Doubles sind Hilfsobjekte, | Test Doubles sind Hilfsobjekte, | ||
| + | In der folgenden Tabelle ist eine kleine Übersicht über verschiedene Test Doubles in aufsteigender Reihenfolge. Es ist grundsätzlich empfohlen, die einfachste (oberste) Variante zu wählen, die funktioniert. | ||
| - | Kleine Übersicht über verschiedene Test Doubles: | + | ^ Double-Typ ^ Beschreibung ^ Entscheidungsfrage ^ |
| - | | + | | Dummy | Platzhalter |
| - | | + | | Stub | Vordefinierte |
| - | | + | | Fake | Vereinfachte |
| - | | + | | Spy | Aufrufe beobachten |
| - | | + | | Mock | Überprüfung direkt bei Aufruf | Ist es sinnvoll, den Test bereits abzubrechen? |
| ==== Dummy ==== | ==== Dummy ==== | ||
| Zeile 69: | Zeile 70: | ||
| expect(service.getUser(1).name).toBe(" | expect(service.getUser(1).name).toBe(" | ||
| </ | </ | ||
| - | Oft ersetzen Fakes in Tests Services wie Datenbanken mit einer einfacheren In-Memory-DB | + | Wie auch in diesem Beispiel, |
| ==== Spy ==== | ==== Spy ==== | ||
| Ein '' | Ein '' | ||
| + | |||
| + | Es ist auch möglich, dass der Spy die echte Logik zusätzlich aufruft. | ||
| <code javascript> | <code javascript> | ||
| - | ... | + | class EmailServiceSpy { |
| + | constructor() { | ||
| + | this.callCount = 0 | ||
| + | this.messages = [] | ||
| + | } | ||
| + | |||
| + | sendEmail(message) { | ||
| + | this.callCount++ | ||
| + | this.messages.push(message) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class UserService { | ||
| + | constructor(emailService) { | ||
| + | this.emailService = emailService | ||
| + | } | ||
| + | |||
| + | registerUser(email) { | ||
| + | this.emailService.sendEmail(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | const emailSpy = new EmailServiceSpy() | ||
| + | const service = new UserService(emailSpy) | ||
| + | |||
| + | service.registerUser(" | ||
| + | |||
| + | if (emailSpy.callCount !== 1) { | ||
| + | throw new Error(" | ||
| + | } | ||
| + | |||
| + | if (emailSpy.messages[0] !== " | ||
| + | throw new Error(" | ||
| + | } | ||
| </ | </ | ||
| Zeile 80: | Zeile 116: | ||
| Ein '' | Ein '' | ||
| <code javascript> | <code javascript> | ||
| - | ... | + | class OrderService { |
| + | constructor(paymentGateway, | ||
| + | this.paymentGateway = paymentGateway | ||
| + | this.repository = repository | ||
| + | } | ||
| + | |||
| + | placeOrder(order) { | ||
| + | this.paymentGateway.authorize(order.amount) | ||
| + | |||
| + | this.repository.save(order) | ||
| + | |||
| + | this.paymentGateway.capture(order.amount) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class PaymentGatewayMock { | ||
| + | constructor() { | ||
| + | this.authorized = false | ||
| + | } | ||
| + | |||
| + | authorize(amount) { | ||
| + | if (this.authorized) { | ||
| + | throw new Error(" | ||
| + | } | ||
| + | this.authorized = true | ||
| + | } | ||
| + | |||
| + | capture(amount) { | ||
| + | if (!this.authorized) { | ||
| + | throw new Error(" | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | const paymentMock = new PaymentGatewayMock() | ||
| + | |||
| + | const repositoryStub = { | ||
| + | save() {} | ||
| + | } | ||
| + | |||
| + | const service = new OrderService(paymentMock, | ||
| + | |||
| + | service.placeOrder({ amount: 100 }) | ||
| </ | </ | ||