Compare commits
10 Commits
e5ba31425c
...
57028fba23
| Author | SHA1 | Date |
|---|---|---|
|
|
57028fba23 | |
|
|
ab1672f29e | |
|
|
bb9a8b9e65 | |
|
|
3ac7b60726 | |
|
|
435b6e7f04 | |
|
|
5380cfd9f3 | |
|
|
7a5c32bf0e | |
|
|
2048508f61 | |
|
|
380efbeb8e | |
|
|
4c38c8616b |
|
|
@ -0,0 +1,228 @@
|
|||
# Fahrplan – Modul Kundenverwaltung (Gruppe H) Ver. 1.2
|
||||
|
||||
**Projekt:** Fakturierungssystem · SE1 Team 2 – Hochschule Mannheim
|
||||
**Modul / Gruppe:** Kundenverwaltung (Gruppe H) · Package `de.hsmannheim.faktura.kunde`
|
||||
**Verantwortlich (dieses Dokument):** Christopher Lampert [3027248]
|
||||
**Gruppe H:** Oleg Akimenko [3028868] (Gruppenleiter), Christopher Lampert [3027248], Kenan Pekarovic [3027541]
|
||||
**Stand:** 26.06.2026
|
||||
**Bezug:** Lastenheft v1.1, Pflichtenheft v1.0, Project Charter v1.1, Modultestplan (KV-Teil), Modultestbericht KV v1.0
|
||||
|
||||
> **Harte Deadline:** Montag, **29.06.2026, 09:00 Uhr** – Abgabe der Artefakte pro Team.
|
||||
> **Präsentation:** Montag, 29.06.2026 im regulären Vorlesungsblock (20–25 Min/Team, 4 Vortragende, je Gruppe ein Vertreter).
|
||||
> **Projektphase laut Charter:** M7 „Puffer & Abnahme" (27.–30.06.2026).
|
||||
|
||||
*Änderung gegenüber v1.1: Phase 6 (Modultests MT-KV-01…11) und Phase 7 (Modultestbericht, P7-1/P7-2) abgeschlossen; Statusmarker, „Aktuelle Position" und Umsetzungsstand aktualisiert; offener Punkt OP-4 (K1 ohne „alle Kunden"-Methode) ergänzt; fehlerhafte Export-Marker entfernt.*
|
||||
|
||||
---
|
||||
|
||||
## 0. So benutzt du diesen Fahrplan
|
||||
|
||||
Jeder Schritt hat einen Status. Aktualisiere ihn, dann kannst du mir jederzeit sagen „ich bin bei P8-1" und ich habe sofort den Kontext.
|
||||
|
||||
**Statuslegende:**
|
||||
`[ ]` offen · `[~]` in Arbeit · `[x]` fertig · `[!]` blockiert / offener Punkt
|
||||
|
||||
**Aktuelle Position:** *Phasen 0–7 (KV-Kern + Modultestbericht) abgeschlossen – nächster Schritt: Phase 8 (Integration) bzw. Team-Abstimmung P7-3.*
|
||||
|
||||
### 🚀 Aktueller Umsetzungsstand (für den neuen Chat-Kontext)
|
||||
Die **Phasen 0 bis 7** der Kundenverwaltung sind umgesetzt: Datenmodell, Persistenz, Validierung, Service-Logik und DP-Schnittstelle stehen, die **11 Modultests MT-KV-01…11** sind grün, und der **Modultestbericht** ist erstellt. Alle entwickelten Klassen sind funktionsfähig und durch JUnit-5-Tests abgedeckt; die Logikschicht erreicht **85 % Line Coverage** (NF-TEST-03 ≥ 60 % erfüllt).
|
||||
|
||||
#### 📁 Erstellte Dateien & Paketstruktur (`de.hsmannheim.faktura.kunde`)
|
||||
* **Wurzelverzeichnis:** `pom.xml` (Maven-Setup für Java 17, JUnit 5 und Jackson) sowie `.gitignore` (ignoriert `target/` und `.idea/`).
|
||||
* **`model`:** `Kunde.java` (spezifikationskonformes POJO mit allen 12 Feldern, PLZ als `String`).
|
||||
* **`repository`:**
|
||||
* `KundeRepository.java` (Interface für Datenhaltung).
|
||||
* `KundeContainer.java` (Hilfsklasse für JSON-Bündelung inkl. ID-Zähler).
|
||||
* `KundeRepositoryJson.java` (Jackson-Implementierung mit fortlaufendem ID-Zähler gegen ID-Wiederverwendung).
|
||||
* **`service`:**
|
||||
* `KundeService.java` (zentrale CRUD-Logik inkl. `finde(long)` für die Beleg-Schnittstelle K3).
|
||||
* `KundeValidator.java` (Pflichtfelder, E-Mail-Format, Bedingung `firmenname || nachname`).
|
||||
* `BelegReferenzPruefer.java` (funktionales Interface zur Entkopplung der GR-05-Löschsperre von Gruppe F).
|
||||
* `ValidierungsException.java` & `LoeschsperreException.java` (Unchecked Exceptions).
|
||||
* **`src/test/java`:**
|
||||
* `KundeModultestTest.java` – konsolidierte Modultestdatei mit **genau 11 Tests** (MT-KV-01…11, 1:1 zum Modultestplan, je `@DisplayName`). Ersetzt die früheren Einzeldateien `KundeServiceTest`, `KundeValidatorTest` und `KundeRepositoryJsonTest` (deren Abdeckung vollständig übernommen wurde; vgl. P10-2 „max. 4 Test-Dateien").
|
||||
* **Abgabe-Artefakt:** `Modultestbericht_Kundenverwaltung_v1_0` (Testergebnisse, Coverage-Nachweis, Abdeckungsübersicht).
|
||||
|
||||
---
|
||||
|
||||
## 1. Ziel & Abgrenzung
|
||||
|
||||
**Im Scope (nur Gruppe H):** Anlegen, Bearbeiten, Suchen und Löschen von Kunden samt Validierung, Persistenz und Modultests – also die fachlichen Anforderungen **F-KV-01 bis F-KV-04** (Herkunft BA-KV-01…04) sowie die mitwirkenden Regeln **GR-05** (Stammdatenschutz) und **NF-ARCH-01** (Persistenz).
|
||||
|
||||
**Nicht im Scope (andere Gruppen):** Produktverwaltung (G), Dokumentenprozess (F), GUI (E). Diese werden hier **nur über die Schnittstellen** berührt (siehe Abschnitt 2).
|
||||
|
||||
**Leitprinzip:** Alles richtet sich nach den vier Projektdokumenten. Abweichungen werden **nicht still aufgelöst**, sondern als offener Punkt in Abschnitt 8 markiert.
|
||||
|
||||
---
|
||||
|
||||
## 2. Kompatibilitätsvertrag mit den anderen Modulen
|
||||
|
||||
Damit die Kundenverwaltung sauber mit den Teilen der anderen Teilnehmer zusammenspielt, müssen diese vier Berührungspunkte exakt eingehalten werden. **Bevor integriert wird, sollten diese Signaturen mit Gruppe E und F gegengeprüft sein.**
|
||||
|
||||
| # | Wer braucht es | Was die Kundenverwaltung liefern muss | Quelle |
|
||||
|---|----------------|----------------------------------------|--------|
|
||||
| K1 | **GUI (Gruppe E)** über IF-01 | `KundeService` mit `anlegen(Kunde): long`, `bearbeiten(Kunde): void`, `suchen(String): List<Kunde>`, `loeschen(long): void` | Pflichtenheft Klassendiagramm (Kap. 7.2), Komponentendiagramm (Kap. 7.1: `KundeAnsicht → KundeService`) |
|
||||
| K2 | **Datenhaltung** über IF-02 | `KundeRepository`-Interface (speichern/findeById/findeAlle/loeschen), JSON-Persistenz dahinter gekapselt | IF-02, NF-ARCH-01/02 |
|
||||
| K3 | **Dokumentenprozess (Gruppe F)** | Kunde ist über `kundeId` (long) referenzierbar; F nutzt `FakeCustomerLookup` und `isCustomerReferenced(...)` in seinen Tests (MT-DP-16). KV muss einen Kunden per ID auflösbar machen (`finde(long): Optional<Kunde>`). | Modultestplan DP (MT-DP-01, MT-DP-16); Pflichtenheft Datenobjekte (kundeId als Referenz in allen Belegen) |
|
||||
| K4 | **Löschsperre GR-05** | Vor dem Löschen prüft `KundeService`, ob der Kunde in einem Beleg referenziert ist → Abfrage gegen `BelegRepository` (Gruppe F). Bei Referenz: Löschen ablehnen. | GR-05; F-KV-04; MT-KV-11 |
|
||||
|
||||
**Daten-Kontrakt „Kunde" (Pflichtenheft Kap. 6.1.2) – verbindlich:**
|
||||
|
||||
| Attribut | Java-Typ | Pflicht | Constraint |
|
||||
|----------|----------|---------|------------|
|
||||
| kundeId | `long` | Pflicht | Fortlaufender, eindeutiger Primärschlüssel |
|
||||
| firmenname | `String` | Pflicht\* | Pflicht, sofern kein Nachname |
|
||||
| nachname | `String` | Pflicht\* | Pflicht, sofern kein Firmenname |
|
||||
| vorname | `String` | Optional | – |
|
||||
| strasse | `String` | Pflicht | Straße + Hausnummer |
|
||||
| plz | `String` | Pflicht | String (führende Nullen erhalten) |
|
||||
| ort | `String` | Pflicht | – |
|
||||
| telefon | `String` | Optional | – |
|
||||
| email | `String` | Optional | Formatvalidierung, falls angegeben |
|
||||
| ustIdNr | `String` | Optional | USt-IdNr. |
|
||||
| lieferadresse | `String` | Optional | abweichende Lieferadresse |
|
||||
| ansprechpartner | `String` | Optional | – |
|
||||
|
||||
\* **Constraint:** `firmenname != null || nachname != null` (mindestens eines befüllt).
|
||||
|
||||
---
|
||||
|
||||
## 3. Technische Vorgaben (aus Pflichtenheft Kap. 2.3)
|
||||
|
||||
- **Sprache:** Java LTS ≥ 17
|
||||
- **Persistenz:** lokale **JSON-Datei** (z. B. Jackson), hinter `KundeRepository` gekapselt → austauschbar (NF-ARCH-02)
|
||||
- **Tests:** **JUnit 5 (Jupiter)** – GUI-unabhängige Logiktests (NF-TEST-02)
|
||||
- **Architektur:** 3-Schichten (ui → service → repository); KV berührt nur `service` + `repository`
|
||||
- **Versionierung:** Git / Gitty, Code-Review je Merge (NF-VER-02)
|
||||
- **Relevante NF-Ziele:** NF-USE-01 (Kunde anlegen < 2 min), NF-PERF-01 (Aktion < 1 s bei 1.000 Kunden), NF-PERF-02 (Liste < 2 s), NF-SEC-01 (kein Klartext von außen), NF-SEC-02 (DSGVO-Löschen)
|
||||
|
||||
---
|
||||
|
||||
## 4. Die Phasen (Schritt für Schritt)
|
||||
|
||||
### Phase 0 – Setup & Abstimmung
|
||||
- `[x]` **P0-1** Git/Gitty: Branch für Gruppe H angelegt und Paketstruktur erstellt.
|
||||
- `[x]` **P0-2** Build-Setup: Maven mit Java 17, JUnit 5 und Jackson in `pom.xml` aufgesetzt.
|
||||
- `[ ]` **P0-3** Schnittstellen K1–K4 mit Gruppe E und F gegenprüfen *(wird bei Integration relevant, Phase 8)*.
|
||||
- `[ ]` **P0-4** Offenen Punkt OP-1 mit Team klären *(Code ist durch Interface entkoppelt)*.
|
||||
|
||||
### Phase 1 – Datenmodell
|
||||
- `[x]` **P1-1** Klasse `Kunde` mit allen 12 Attributen erstellt (`plz` als `String`).
|
||||
- `[x]` **P1-2** Getter/Setter und `equals`/`hashCode` über `kundeId` implementiert.
|
||||
- `[x]` **P1-3** JSON-Serialisierbarkeit via Jackson durch leeren Konstruktor sichergestellt.
|
||||
|
||||
### Phase 2 – Persistenz (IF-02 / NF-ARCH-01/02)
|
||||
- `[x]` **P2-1** Interface `KundeRepository` mit CRUD-Signaturen definiert.
|
||||
- `[x]` **P2-2** `KundeRepositoryJson` lädt/speichert lokale JSON-Datei via Jackson.
|
||||
- `[x]` **P2-3** Fortlaufende ID-Vergabe über mitgespeicherten Zähler gelöst (kein ID-Reuse nach Löschung).
|
||||
- `[x]` **P2-4** Persistenz-Roundtrip geprüft (jetzt in MT-KV-06 enthalten).
|
||||
|
||||
### Phase 3 – Validierung
|
||||
- `[x]` **P3-1** Pflichtfeldprüfung für `strasse`, `plz`, `ort` in `KundeValidator` eingebaut.
|
||||
- `[x]` **P3-2** Constraint `firmenname != null || nachname != null` umgesetzt.
|
||||
- `[x]` **P3-3** E-Mail-Formatprüfung per Regex integriert.
|
||||
- `[x]` **P3-4** `ValidierungsException` erstellt; wird vor dem Speichern geworfen, um ungültige Daten zu blockieren.
|
||||
|
||||
### Phase 4 – Logik: `KundeService` (F-KV-01…04)
|
||||
- `[x]` **P4-1** `anlegen(Kunde)` validiert, erzwingt ID-Vergabe und persistiert. · **F-KV-01 / BA-KV-01**
|
||||
- `[x]` **P4-2** `bearbeiten(Kunde)` prüft Existenz, validiert und speichert. · **F-KV-02 / BA-KV-02**
|
||||
- `[x]` **P4-3** `suchen(String)` filtert über Name (case-insensitive) und Kundennummer. · **F-KV-03 / BA-KV-03**
|
||||
- `[x]` **P4-4** `loeschen(long)` prüft Existenz und wirft bei aktiver Referenz eine `LoeschsperreException`. · **F-KV-04 / BA-KV-04**
|
||||
- `[x]` **P4-5** GR-05-Löschsperre über das Interface `BelegReferenzPruefer` vollständig vorbereitet und isoliert getestet.
|
||||
|
||||
### Phase 5 – Schnittstelle zum Dokumentenprozess (K3)
|
||||
- `[x]` **P5-1** `KundeService.finde(long): Optional<Kunde>` als Schnittstelle für Gruppe F bereitgestellt.
|
||||
- `[ ]` **P5-2** Mit Gruppe F genaue Aufrufrichtung für `isCustomerReferenced` abstimmen *(offen, Integration)*.
|
||||
|
||||
### Phase 6 – Modultests (JUnit 5, MT-KV-01…11) ✅ abgeschlossen
|
||||
*Die fachliche Logik wurde in genau die 11 im Modultestplan geforderten Testmethoden überführt – konsolidiert in `KundeModultestTest`, jeweils mit `@DisplayName` (MT-KV-ID sichtbar im Testlauf):*
|
||||
|
||||
- `[x]` **P6-01** MT-KV-01 Kunde mit allen Pflichtattributen anlegen → gespeichert · BA-KV-01
|
||||
- `[x]` **P6-02** MT-KV-02 ohne Firmenname/Nachname → abgelehnt · BA-KV-01
|
||||
- `[x]` **P6-03** MT-KV-03 ohne Straße → abgelehnt · BA-KV-01
|
||||
- `[x]` **P6-04** MT-KV-04 ungültige E-Mail „kunde@" → abgelehnt · BA-KV-01
|
||||
- `[x]` **P6-05** MT-KV-05 Telefonnummer ändern → gespeichert · BA-KV-02
|
||||
- `[x]` **P6-06** MT-KV-06 Persistenz nach Neuladen → unverändert · BA-KV-02, NF-ARCH-01
|
||||
- `[x]` **P6-07** MT-KV-07 Suche über Namen „Muster" → gefunden · BA-KV-03
|
||||
- `[x]` **P6-08** MT-KV-08 Suche über Kundennummer → gefunden · BA-KV-03
|
||||
- `[x]` **P6-09** MT-KV-09 Suche ohne Treffer → leeres Ergebnis · BA-KV-03
|
||||
- `[x]` **P6-10** MT-KV-10 nicht referenzierten Kunden löschen → entfernt · BA-KV-04
|
||||
- `[x]` **P6-11** MT-KV-11 referenzierten Kunden löschen → abgewiesen · BA-KV-04, GR-05
|
||||
- `[x]` **P6-12** Alle 11 Tests grün; Coverage nachgewiesen: **85 % Line Coverage** im Paket `…kunde.service` (NF-TEST-03 ≥ 60 % erfüllt).
|
||||
|
||||
### Phase 7 – Abgabe-Artefakt: Modultestbericht ✅ weitgehend abgeschlossen
|
||||
- `[x]` **P7-1** Testlauf dokumentiert: je MT-KV-Fall Ergebnis (bestanden), Datum (26.06.2026), Tester.
|
||||
- `[x]` **P7-2** Abdeckungsübersicht aus dem Modultestplan (BA-KV-01→MT-KV-01…04 usw.) als Nachweis übernommen.
|
||||
- `[ ]` **P7-3** Mit Team klären: **max. 4 Dateien** insgesamt → KV-Bericht eigene Datei **oder** in gemeinsame Test-Datei integriert (Koordination mit G/F/E; siehe OP-2).
|
||||
|
||||
### Phase 8 – Integration mit anderen Modulen
|
||||
- `[ ]` **P8-1** GUI (E): `KundeAnsicht` ruft `KundeService` – Smoke-Test Anlegen/Suchen/Löschen aus der Oberfläche.
|
||||
- `[ ]` **P8-2** Belege (F): echter Kunde im Angebot referenzierbar; GR-05-Löschsperre greift im integrierten System (MT-DP-16 ↔ MT-KV-11).
|
||||
- `[ ]` **P8-3** Gesamtsystem startet, KV-CRUD lauffähig (AK-02 Charter).
|
||||
|
||||
### Phase 9 – Präsentation (KV-Anteil)
|
||||
Pflichtinhalte laut Aufgabenstellung – als KV-Vertreter (1 Person je Gruppe) vorbereiten:
|
||||
- `[ ]` **P9-1** Demo-Anteil: Kunde anlegen → suchen → bearbeiten → Löschsperre zeigen (referenzierter Kunde).
|
||||
- `[ ]` **P9-2** **KI-Einsatz:** wo eingesetzt, wie gut hat es funktioniert (konkrete KV-Beispiele).
|
||||
- `[ ]` **P9-3** **Was nächstes Mal anders:** ehrliche Lessons learned aus der KV-Umsetzung.
|
||||
- `[ ]` **P9-4** **Modultestplan-Ergebnisse** der KV präsentieren (Abdeckung + Pass-Quote 100 %).
|
||||
- `[ ]` **P9-5** **Traceability-Stichprobe vorbereiten:** Kette **BA-KV-0x → F-KV-0x → MT-KV-xx → AT-KV-xx** auswendig/griffbereit (Prof prüft stichprobenartig).
|
||||
|
||||
### Phase 10 – Abgabe & Generalprobe
|
||||
- `[ ]` **P10-1** Code gemergt, Reviews abgeschlossen (NF-VER-02), Tests grün im Hauptbranch.
|
||||
- `[ ]` **P10-2** Testbericht + Folien im Team konsolidiert (max. 4 Test-Dateien, genau 1 Foliendatei).
|
||||
- `[ ]` **P10-3** **Abgabe bis Mo 29.06. 09:00 Uhr.**
|
||||
- `[ ]` **P10-4** Generalprobe Vortrag + Zeitmessung (20–25 Min Team-Budget).
|
||||
|
||||
---
|
||||
|
||||
## 5. Traceability-Matrix Kundenverwaltung (für die Stichprobenprüfung)
|
||||
|
||||
| Anforderung (LH) | Pflichtenheft | Modultests | Akzeptanztest (LH) |
|
||||
|------------------|---------------|------------|--------------------|
|
||||
| BA-KV-01 Kunde anlegen | F-KV-01 | MT-KV-01 … MT-KV-04 | AT-KV-01, AT-KV-02 |
|
||||
| BA-KV-02 Kunde bearbeiten | F-KV-02 | MT-KV-05, MT-KV-06 | AT-KV-03, AT-KV-04 |
|
||||
| BA-KV-03 Kunde suchen | F-KV-03 | MT-KV-07 … MT-KV-09 | AT-KV-05, AT-KV-06 |
|
||||
| BA-KV-04 Kunde löschen | F-KV-04 | MT-KV-10, MT-KV-11 | AT-KV-07, AT-KV-08 |
|
||||
| GR-05 Stammdatenschutz | F-KV-04 (i.V.m. GR-05) | MT-KV-11 | – |
|
||||
| NF-ARCH-01 Persistenz | NF-ARCH-01 | MT-KV-06 | AT-NF-… |
|
||||
|
||||
---
|
||||
|
||||
## 6. Zeitplan bis Montag
|
||||
|
||||
| Tag | Fokus | Status |
|
||||
|-----|-------|--------|
|
||||
| **Do 25.06** | Phase 0 + Phase 1 (Setup, Schnittstellen, Datenmodell) | erledigt |
|
||||
| **Fr 26.06** | Phase 2–7 (Persistenz, Validierung, Service-Logik, DP-Schnittstelle, 11 Modultests grün, Modultestbericht) | erledigt – **KV ist dem Zeitplan voraus** |
|
||||
| **Sa 27.06** | Puffer + Vorbereitung Integration (Phase 8) und Folien (Phase 9) | offen |
|
||||
| **So 28.06** | Phase 8 + Phase 9 (Integration, Folien, Traceability-Stichprobe) | offen |
|
||||
| **Mo 29.06 vor 09:00** | Phase 10 (Konsolidierung, Abgabe, Generalprobe) | offen |
|
||||
|
||||
---
|
||||
|
||||
## 7. Definition of Done (Kundenverwaltung)
|
||||
|
||||
- `[x]` F-KV-01 bis F-KV-04 implementiert und über `KundeService` aufrufbar (K1).
|
||||
- `[x]` Persistenz über `KundeRepository`/JSON, Daten überleben Neustart (NF-ARCH-01).
|
||||
- `[x]` Validierung greift (Pflichtfelder, firmenname||nachname, E-Mail-Format).
|
||||
- `[~]` GR-05-Löschsperre: isoliert getestet (MT-KV-11); im **integrierten** System noch nachzuweisen (Phase 8).
|
||||
- `[x]` MT-KV-01…11 alle grün, Coverage ≥ 60 % im `kunde`-Paket (85 % Line in `…service`).
|
||||
- `[~]` Modultestbericht erstellt; Integration ins Team-Sammelartefakt offen (P7-3).
|
||||
- `[~]` Traceability BA→F→MT lückenlos und vorführbar; AT-KV-Akzeptanztests teamseitig.
|
||||
- `[ ]` In Gesamtsystem integriert (GUI + Belege), Code gereviewt und gemergt (Phase 8 / 10).
|
||||
|
||||
---
|
||||
|
||||
## 8. Offene Punkte (nicht still aufgelöst)
|
||||
|
||||
| ID | Dokument / Stelle | Beschreibung | Vorschlag |
|
||||
|----|-------------------|--------------|-----------|
|
||||
| OP-1 | Pflichtenheft Klassendiagramm (Kap. 7.2) vs. GR-05 | Diagramm zeigt `KundeService ..> ProduktRepository`; GR-05-Text fordert Referenzprüfung über `BelegRepository`. Für die Löschsperre F-KV-04/MT-KV-11 ist das **BelegRepository** maßgeblich. | Im Code gegen `BelegRepository` prüfen (über `BelegReferenzPruefer` umgesetzt); Diagramm-Abhängigkeit als Doku-Inkonsistenz an Team/Prüfer melden. |
|
||||
| OP-2 | Abgabe-Format | „max. 4 Dateien" für Testberichte bei 4 Modulen → Aufteilung 1 Datei/Modul **oder** 1 Sammeldatei? | Team-Entscheidung vor So 28.06; KV-Bericht entsprechend zuschneiden (P7-3). |
|
||||
| OP-3 | Schnittstelle K3 (Lookup-Richtung) | Genaue Aufrufrichtung zwischen KV und Gruppe F für `isCustomerReferenced` final festzurren. | In P0-3 mit Gruppe F bestätigen. |
|
||||
| OP-4 | Vertrag K1 vs. GUI-Übersicht (Gruppe E) | K1 enthält keine Methode zum Auflisten **aller** Kunden; `suchen("")` liefert bewusst eine leere Liste. Die `KundeAnsicht` kann die Gesamtliste so nicht über den Service beziehen. Kein Code-Fehler (K1 ist exakt umgesetzt), aber eine Vertragslücke. | Mit Gruppe E klären: entweder `List<Kunde> alle()` im `KundeService` ergänzen oder Konvention „leere Suche = alle Kunden" festlegen. Vor Phase 8 entscheiden. |
|
||||
|
||||
---
|
||||
|
||||
*Aktualisiere bei jeder Session die Zeile „Aktuelle Position" in Abschnitt 0 und die Status-Marker. Damit kann der Fortschritt jederzeit punktgenau aufgegriffen werden.*
|
||||
Binary file not shown.
|
|
@ -0,0 +1,117 @@
|
|||
---
|
||||
title: "Modultestbericht – Kundenverwaltung"
|
||||
subtitle: "SE1 Team 2 – Hochschule Mannheim · Modul Software Engineering 1"
|
||||
author: "Christopher Lampert"
|
||||
date: "26.06.2026"
|
||||
lang: de-DE
|
||||
geometry: "left=2.2cm,right=2.2cm,top=2cm,bottom=2cm"
|
||||
fontsize: 10pt
|
||||
mainfont: "Latin Modern Roman"
|
||||
colorlinks: true
|
||||
linkcolor: "blue"
|
||||
urlcolor: "blue"
|
||||
numbersections: false
|
||||
header-includes:
|
||||
- \setlength{\tabcolsep}{4pt}
|
||||
- \renewcommand{\arraystretch}{1.12}
|
||||
- \usepackage{etoolbox}
|
||||
- \AtBeginEnvironment{longtable}{\small}
|
||||
- \usepackage{newunicodechar}
|
||||
- \newunicodechar{≥}{\ensuremath{\geq}}
|
||||
- \newunicodechar{≤}{\ensuremath{\leq}}
|
||||
---
|
||||
|
||||
# Modultestbericht – Modul Kundenverwaltung (Gruppe H)
|
||||
|
||||
**Modul:** Software Engineering 1
|
||||
**Team / Gruppe:** SE1 Team 2 – Gruppe H (Kundenverwaltung), Package `de.hsmannheim.faktura.kunde`
|
||||
**Version:** 1.0
|
||||
**Stand:** 26.06.2026
|
||||
**Autor / Tester:** Christopher Lampert
|
||||
**Bezug:** Modultestplan (KV-Teil), Pflichtenheft v1.1, Lastenheft v1.1, Fahrplan Kundenverwaltung v1.1
|
||||
|
||||
Dieser Bericht dokumentiert die Durchführung und das Ergebnis der Modultests des Moduls **Kundenverwaltung**. Er weist nach, dass die im Modultestplan definierten Testfälle MT-KV-01 bis MT-KV-11 umgesetzt, ausgeführt und bestanden wurden, und belegt die geforderte Testabdeckung der Logikschicht (NF-TEST-03).
|
||||
|
||||
---
|
||||
|
||||
## Freigabeübersicht
|
||||
|
||||
| Funktion | Name | Rolle / Gruppe | Datum |
|
||||
|--------------|----------------------------|------------------------------------|------------|
|
||||
| Ersteller | Christopher Lampert | Autor / Tester, Gruppe H | 26.06.2026 |
|
||||
| Prüfer | Oleg Akimenko | Gruppenleiter Gruppe H | _(offen)_ |
|
||||
| Freigebender | SE1 Team 2 (Gruppenleiter) | Projektleitung / Freigabe | _(offen)_ |
|
||||
|
||||
---
|
||||
|
||||
## 1. Testgegenstand und Vorgehen
|
||||
|
||||
Geprüft wird die fachliche Logik der Kundenverwaltung – die Anforderungen **F-KV-01 … F-KV-04**, die Geschäftsregel **GR-05** (Stammdatenschutz / Löschsperre) und **NF-ARCH-01** (Persistenz) – über die öffentliche Schnittstelle des `KundeService`.
|
||||
|
||||
Die Tests sind als automatisierte JUnit-5-Tests **ohne GUI-Abhängigkeit** umgesetzt (NF-TEST-02) und in der Datei `KundeModultestTest.java` zusammengefasst. Jeder Testfall bildet **genau einen** Modultestplan-Fall ab (1:1) und trägt dessen Bezeichnung als `@DisplayName`, sodass das Testprotokoll unmittelbar aus dem Testlauf hervorgeht. Die Validierungs- und Persistenzschicht wird dabei real durchlaufen (echtes `KundeValidator`- und JSON-`KundeRepository`-Objekt je Test über `@TempDir`); lediglich die Beleg-Referenzprüfung der Löschsperre (GR-05) wird über das Interface `BelegReferenzPruefer` gesteuert. Die Ausführung erfolgt reproduzierbar über Maven (`mvn test`) bzw. den IntelliJ-Testrunner.
|
||||
|
||||
## 2. Testumgebung
|
||||
|
||||
| Aspekt | Festlegung |
|
||||
|-------------------------------------|------------------------------------------------------------------------------|
|
||||
| Programmiersprache | Java 17 (LTS); `maven.compiler.release=17` |
|
||||
| Test-Framework | JUnit 5 (Jupiter) 5.10.2 |
|
||||
| Build / Ausführung | Maven, `maven-surefire-plugin` 3.2.5 |
|
||||
| Persistenz (im Test real genutzt) | Jackson Databind 2.17.1; lokale JSON-Datei je Test (`@TempDir`) |
|
||||
| Abdeckungsmessung | IntelliJ IDEA Coverage Runner |
|
||||
| Testdatei | `src/test/java/de/hsmannheim/faktura/kunde/service/KundeModultestTest.java` |
|
||||
|
||||
## 3. Testergebnisse
|
||||
|
||||
Alle elf Modultests wurden am **26.06.2026** ausgeführt und **bestanden**.
|
||||
|
||||
| Testfall | Testziel / Beschreibung | Anforderung | Ergebnis | Datum | Tester |
|
||||
|----------|---------------------------------------------------|----------------------|-----------|------------|------------|
|
||||
| MT-KV-01 | Kunde mit vollständigen Pflichtattributen anlegen | BA-KV-01 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-02 | Kunde ohne Firmenname bzw. Nachname anlegen | BA-KV-01 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-03 | Kunde ohne Straße anlegen | BA-KV-01 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-04 | Kunde mit ungültigem E-Mail-Format anlegen | BA-KV-01 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-05 | Vorhandenen Kunden bearbeiten | BA-KV-02 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-06 | Persistenz geänderter Kundendaten prüfen | BA-KV-02, NF-ARCH-01 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-07 | Kunde über Namen suchen | BA-KV-03 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-08 | Kunde über Kundennummer suchen | BA-KV-03 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-09 | Nicht vorhandenen Kunden suchen | BA-KV-03 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-10 | Nicht referenzierten Kunden löschen | BA-KV-04 | bestanden | 26.06.2026 | C. Lampert |
|
||||
| MT-KV-11 | Referenzierten Kunden löschen | BA-KV-04, GR-05 | bestanden | 26.06.2026 | C. Lampert |
|
||||
|
||||
**Zusammenfassung:** 11 von 11 Testfällen bestanden (Pass-Quote 100 %); 0 fehlgeschlagen; 0 übersprungen.
|
||||
|
||||
## 4. Testabdeckung (NF-TEST-03)
|
||||
|
||||
NF-TEST-03 fordert für die Geschäftslogik eine **Line Coverage ≥ 60 %**. Gemessene Abdeckung der Logikschicht (`de.hsmannheim.faktura.kunde.service`) durch `KundeModultestTest`:
|
||||
|
||||
| Geltungsbereich | Klassen | Methoden | Zeilen (Line) | Branches |
|
||||
|------------------------------------------|--------------|----------------|-----------------|-----------------|
|
||||
| Logikschicht (`…kunde.service`) | 100 % (4/4) | 100 % (13/13) | 85 % (41/48) | 73 % (25/34) |
|
||||
|
||||
Mit **85 % Line Coverage** der Geschäftslogik bei **100 % abgedeckten Methoden** ist die geforderte Schwelle von 60 % deutlich übertroffen. **NF-TEST-03 ist erfüllt.**
|
||||
|
||||
## 5. Abdeckungsübersicht (Anforderung → Testfälle)
|
||||
|
||||
Übernommen aus dem Modultestplan (KV-Teil). Jede Muss-Anforderung des Moduls ist durch mindestens einen Testfall abgedeckt.
|
||||
|
||||
| Anforderung | Abgedeckte Testfälle |
|
||||
|---------------------------|-----------------------|
|
||||
| BA-KV-01 Kunde anlegen | MT-KV-01 bis MT-KV-04 |
|
||||
| BA-KV-02 Kunde bearbeiten | MT-KV-05, MT-KV-06 |
|
||||
| BA-KV-03 Kunde suchen | MT-KV-07 bis MT-KV-09 |
|
||||
| BA-KV-04 Kunde löschen | MT-KV-10, MT-KV-11 |
|
||||
| GR-05 Stammdatenschutz | MT-KV-11 |
|
||||
| NF-ARCH-01 Persistenz | MT-KV-06 |
|
||||
|
||||
## 6. Fazit
|
||||
|
||||
Die fachlichen Anforderungen des Moduls Kundenverwaltung sind durch die Modultests MT-KV-01 bis MT-KV-11 vollständig abgedeckt und nachweislich erfüllt. Alle Tests bestehen (Pass-Quote 100 %), und die geforderte Testabdeckung der Logikschicht ist mit 85 % Line Coverage erreicht (NF-TEST-03). Die Traceability-Kette **BA-KV-0x → F-KV-0x → MT-KV-xx** ist über Modultestplan und diesen Bericht lückenlos belegbar.
|
||||
|
||||
---
|
||||
|
||||
## Änderungshistorie
|
||||
|
||||
| Version | Datum | Autor | Änderung |
|
||||
|---------|------------|---------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| 1.0 | 26.06.2026 | Christopher Lampert | Initiale Erstellung des Modultestberichts: Testergebnisse MT-KV-01…11, Coverage-Nachweis (NF-TEST-03), Abdeckungsübersicht. |
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
|
@ -1,40 +0,0 @@
|
|||
package de.hsmannheim.faktura.kunde.repository;
|
||||
|
||||
import de.hsmannheim.faktura.kunde.model.Kunde;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class KundeRepositoryJsonTest {
|
||||
|
||||
@Test
|
||||
void persistenz_ueberlebt_neustart(@TempDir Path tempDir) {
|
||||
File datei = tempDir.resolve("kunden.json").toFile();
|
||||
|
||||
// 1. Repository anlegen und einen Kunden speichern
|
||||
KundeRepository repo1 = new KundeRepositoryJson(datei);
|
||||
Kunde kunde = new Kunde();
|
||||
kunde.setNachname("Mustermann");
|
||||
kunde.setStrasse("Hauptstr. 1");
|
||||
kunde.setPlz("01067"); // führende Null!
|
||||
kunde.setOrt("Dresden");
|
||||
long id = repo1.speichern(kunde);
|
||||
|
||||
// 2. Neues Repository auf dieselbe Datei = simulierter Neustart
|
||||
KundeRepository repo2 = new KundeRepositoryJson(datei);
|
||||
Optional<Kunde> geladen = repo2.findeById(id);
|
||||
|
||||
// 3. Kunde ist unverändert wiederhergestellt
|
||||
assertTrue(geladen.isPresent(), "Kunde sollte nach Neustart vorhanden sein");
|
||||
assertEquals("Mustermann", geladen.get().getNachname());
|
||||
assertEquals("01067", geladen.get().getPlz(),
|
||||
"Führende Null der PLZ muss erhalten bleiben");
|
||||
assertEquals("Dresden", geladen.get().getOrt());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package de.hsmannheim.faktura.kunde.service;
|
||||
|
||||
import de.hsmannheim.faktura.kunde.model.Kunde;
|
||||
import de.hsmannheim.faktura.kunde.repository.KundeRepositoryJson;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Modultests der Kundenverwaltung (Gruppe H) – Phase 6 des Fahrplans.
|
||||
*
|
||||
* <p>Diese Klasse überführt die fachliche Logik in exakt die elf im Modultestplan
|
||||
* geforderten Testfälle MT-KV-01 … MT-KV-11 (1:1-Abbildung). Jeder Test trägt den
|
||||
* Modultestplan-Titel als {@code @DisplayName}, sodass der Testlauf direkt als
|
||||
* Modultestbericht (Phase 7, P7-1) verwendbar ist.</p>
|
||||
*
|
||||
* <p>Die Tests laufen GUI-unabhängig (NF-TEST-02) gegen die echte Service-,
|
||||
* Validator- und JSON-Repository-Schicht; nur die Beleg-Referenzprüfung der
|
||||
* GR-05-Löschsperre wird über das Interface {@link BelegReferenzPruefer}
|
||||
* gesteuert.</p>
|
||||
*
|
||||
* <p>Diese Datei ersetzt die zuvor getrennten Testklassen {@code KundeServiceTest},
|
||||
* {@code KundeValidatorTest} und {@code KundeRepositoryJsonTest}; deren Abdeckung
|
||||
* geht hier vollständig auf (vgl. P10-2 „max. 4 Test-Dateien").</p>
|
||||
*
|
||||
* <p>Abgedeckte Anforderungen: BA-KV-01 … BA-KV-04, GR-05, NF-ARCH-01.</p>
|
||||
*/
|
||||
@TestMethodOrder(MethodOrderer.MethodName.class)
|
||||
@DisplayName("Modultests Kundenverwaltung (MT-KV-01 … MT-KV-11)")
|
||||
class KundeModultestTest {
|
||||
|
||||
private KundeService service;
|
||||
private File datei;
|
||||
private boolean kundeIstReferenziert; // steuert die GR-05-Löschsperre im Test
|
||||
private BelegReferenzPruefer belegPruefer;
|
||||
|
||||
@BeforeEach
|
||||
void setUp(@TempDir Path tempDir) {
|
||||
datei = tempDir.resolve("kunden.json").toFile();
|
||||
kundeIstReferenziert = false;
|
||||
belegPruefer = kundeId -> kundeIstReferenziert;
|
||||
service = new KundeService(new KundeRepositoryJson(datei),
|
||||
new KundeValidator(), belegPruefer);
|
||||
}
|
||||
|
||||
/** Gültiger Kunde mit Firmenname (entspricht „Muster GmbH" aus MT-KV-01 / MT-KV-07). */
|
||||
private Kunde musterKunde() {
|
||||
Kunde k = new Kunde();
|
||||
k.setFirmenname("Muster GmbH");
|
||||
k.setStrasse("Hauptstr. 1");
|
||||
k.setPlz("68159");
|
||||
k.setOrt("Mannheim");
|
||||
return k;
|
||||
}
|
||||
|
||||
// ───────────────────────────── BA-KV-01: Kunde anlegen ─────────────────────────────
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-01: Kunde mit vollständigen Pflichtattributen anlegen")
|
||||
void mtKv01_kundeMitPflichtattributen_wirdGespeichert() { // BA-KV-01
|
||||
long id = service.anlegen(musterKunde());
|
||||
|
||||
assertTrue(id > 0, "Es muss eine fortlaufende kundeId vergeben werden");
|
||||
assertEquals(1, service.suchen("Muster").size(),
|
||||
"Angelegter Kunde muss in der Kundenliste auffindbar sein");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-02: Kunde ohne Firmenname bzw. Nachname anlegen")
|
||||
void mtKv02_ohneFirmennameUndNachname_wirdAbgelehnt() { // BA-KV-01
|
||||
Kunde k = musterKunde();
|
||||
k.setFirmenname(null); // nachname ist ohnehin null -> beide leer
|
||||
|
||||
assertThrows(ValidierungsException.class, () -> service.anlegen(k));
|
||||
assertTrue(service.suchen("Muster").isEmpty(), "Es darf nichts gespeichert werden");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-03: Kunde ohne Straße anlegen")
|
||||
void mtKv03_ohneStrasse_wirdAbgelehnt() { // BA-KV-01
|
||||
Kunde k = musterKunde();
|
||||
k.setStrasse(null);
|
||||
|
||||
assertThrows(ValidierungsException.class, () -> service.anlegen(k));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-04: Kunde mit ungültigem E-Mail-Format anlegen")
|
||||
void mtKv04_ungueltigeEmail_wirdAbgelehnt() { // BA-KV-01
|
||||
Kunde k = musterKunde();
|
||||
k.setEmail("kunde@");
|
||||
|
||||
assertThrows(ValidierungsException.class, () -> service.anlegen(k));
|
||||
}
|
||||
|
||||
// ──────────────────────────── BA-KV-02: Kunde bearbeiten ───────────────────────────
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-05: Vorhandenen Kunden bearbeiten")
|
||||
void mtKv05_telefonnummerAendern_wirdGespeichert() { // BA-KV-02
|
||||
long id = service.anlegen(musterKunde());
|
||||
Kunde k = service.finde(id).orElseThrow();
|
||||
k.setTelefon("0621 12345");
|
||||
|
||||
service.bearbeiten(k);
|
||||
|
||||
assertEquals("0621 12345", service.finde(id).orElseThrow().getTelefon(),
|
||||
"Geänderte Telefonnummer muss gespeichert und angezeigt werden");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-06: Persistenz geänderter Kundendaten prüfen")
|
||||
void mtKv06_geaenderteDaten_ueberlebenNeuladen() { // BA-KV-02, NF-ARCH-01
|
||||
// Kunde mit führender Null in der PLZ -> prüft zugleich den String-PLZ-Typ (Kap. 6.1.2)
|
||||
Kunde k = new Kunde();
|
||||
k.setNachname("Mustermann");
|
||||
k.setStrasse("Hauptstr. 1");
|
||||
k.setPlz("01067");
|
||||
k.setOrt("Dresden");
|
||||
long id = service.anlegen(k);
|
||||
|
||||
Kunde geladen = service.finde(id).orElseThrow();
|
||||
geladen.setTelefon("0351 99999");
|
||||
service.bearbeiten(geladen);
|
||||
|
||||
// Neues Repository/Service auf dieselbe Datei = simulierter Neustart
|
||||
KundeService nachNeustart = new KundeService(new KundeRepositoryJson(datei),
|
||||
new KundeValidator(), belegPruefer);
|
||||
Kunde wieder = nachNeustart.finde(id).orElseThrow();
|
||||
|
||||
assertEquals("0351 99999", wieder.getTelefon(), "Geänderte Daten müssen erhalten bleiben");
|
||||
assertEquals("01067", wieder.getPlz(), "Führende Null der PLZ muss erhalten bleiben");
|
||||
assertEquals("Mustermann", wieder.getNachname());
|
||||
}
|
||||
|
||||
// ──────────────────────────── BA-KV-03: Kunde suchen ───────────────────────────────
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-07: Kunde über Namen suchen")
|
||||
void mtKv07_sucheUeberNamen_findetKunden() { // BA-KV-03
|
||||
service.anlegen(musterKunde()); // „Muster GmbH"
|
||||
|
||||
List<Kunde> treffer = service.suchen("Muster");
|
||||
|
||||
assertEquals(1, treffer.size());
|
||||
assertEquals("Muster GmbH", treffer.get(0).getFirmenname());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-08: Kunde über Kundennummer suchen")
|
||||
void mtKv08_sucheUeberKundennummer_findetKunden() { // BA-KV-03
|
||||
long id = service.anlegen(musterKunde());
|
||||
|
||||
List<Kunde> treffer = service.suchen(String.valueOf(id));
|
||||
|
||||
assertEquals(1, treffer.size());
|
||||
assertEquals(id, treffer.get(0).getKundeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-09: Nicht vorhandenen Kunden suchen")
|
||||
void mtKv09_sucheOhneTreffer_istLeer() { // BA-KV-03
|
||||
service.anlegen(musterKunde());
|
||||
|
||||
assertTrue(service.suchen("Gibtsnicht").isEmpty(),
|
||||
"Ohne Treffer muss eine leere Liste zurückgegeben werden");
|
||||
}
|
||||
|
||||
// ──────────────────────────── BA-KV-04: Kunde löschen ──────────────────────────────
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-10: Nicht referenzierten Kunden löschen")
|
||||
void mtKv10_nichtReferenzierterKunde_wirdEntfernt() { // BA-KV-04
|
||||
long id = service.anlegen(musterKunde());
|
||||
kundeIstReferenziert = false;
|
||||
|
||||
service.loeschen(id);
|
||||
|
||||
assertTrue(service.finde(id).isEmpty(), "Kunde muss entfernt sein");
|
||||
assertTrue(service.suchen("Muster").isEmpty(),
|
||||
"Gelöschter Kunde darf nicht mehr gefunden werden");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("MT-KV-11: Referenzierten Kunden löschen")
|
||||
void mtKv11_referenzierterKunde_wirdAbgewiesen() { // BA-KV-04, GR-05
|
||||
long id = service.anlegen(musterKunde());
|
||||
kundeIstReferenziert = true;
|
||||
|
||||
assertThrows(LoeschsperreException.class, () -> service.loeschen(id));
|
||||
assertTrue(service.finde(id).isPresent(),
|
||||
"Referenzierter Kunde muss erhalten bleiben");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
package de.hsmannheim.faktura.kunde.service;
|
||||
|
||||
import de.hsmannheim.faktura.kunde.model.Kunde;
|
||||
import de.hsmannheim.faktura.kunde.repository.KundeRepository;
|
||||
import de.hsmannheim.faktura.kunde.repository.KundeRepositoryJson;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class KundeServiceTest {
|
||||
|
||||
private KundeService service;
|
||||
private boolean kundeIstReferenziert; // steuert den BelegReferenzPruefer im Test
|
||||
|
||||
@BeforeEach
|
||||
void setUp(@TempDir Path tempDir) {
|
||||
File datei = tempDir.resolve("kunden.json").toFile();
|
||||
KundeRepository repository = new KundeRepositoryJson(datei);
|
||||
KundeValidator validator = new KundeValidator();
|
||||
BelegReferenzPruefer belegPruefer = kundeId -> kundeIstReferenziert;
|
||||
service = new KundeService(repository, validator, belegPruefer);
|
||||
kundeIstReferenziert = false;
|
||||
}
|
||||
|
||||
private Kunde gueltigerKunde() {
|
||||
Kunde k = new Kunde();
|
||||
k.setNachname("Mustermann");
|
||||
k.setStrasse("Hauptstr. 1");
|
||||
k.setPlz("68159");
|
||||
k.setOrt("Mannheim");
|
||||
return k;
|
||||
}
|
||||
|
||||
@Test
|
||||
void anlegen_vergibtIdUndPersistiert() { // BA-KV-01
|
||||
long id = service.anlegen(gueltigerKunde());
|
||||
assertTrue(id > 0);
|
||||
assertEquals(1, service.suchen("Mustermann").size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void anlegen_ungueltig_wirdNichtGespeichert() { // P3-4 im Service
|
||||
Kunde k = gueltigerKunde();
|
||||
k.setNachname(null);
|
||||
assertThrows(ValidierungsException.class, () -> service.anlegen(k));
|
||||
assertTrue(service.suchen("Mustermann").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void bearbeiten_aendertGespeichertenKunden() { // BA-KV-02
|
||||
service.anlegen(gueltigerKunde());
|
||||
Kunde k = service.suchen("Mustermann").get(0);
|
||||
k.setTelefon("0621 12345");
|
||||
service.bearbeiten(k);
|
||||
assertEquals("0621 12345", service.suchen("Mustermann").get(0).getTelefon());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suchen_ueberKundennummer_findet() { // BA-KV-03 / MT-KV-08
|
||||
long id = service.anlegen(gueltigerKunde());
|
||||
assertEquals(1, service.suchen(String.valueOf(id)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suchen_ohneTreffer_istLeer() { // BA-KV-03 / MT-KV-09
|
||||
service.anlegen(gueltigerKunde());
|
||||
assertTrue(service.suchen("Gibtsnicht").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loeschen_nichtReferenziert_entfernt() { // BA-KV-04 / MT-KV-10
|
||||
long id = service.anlegen(gueltigerKunde());
|
||||
kundeIstReferenziert = false;
|
||||
service.loeschen(id);
|
||||
assertTrue(service.suchen("Mustermann").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loeschen_referenziert_wirdAbgewiesen() { // BA-KV-04 / GR-05 / MT-KV-11
|
||||
long id = service.anlegen(gueltigerKunde());
|
||||
kundeIstReferenziert = true;
|
||||
assertThrows(LoeschsperreException.class, () -> service.loeschen(id));
|
||||
assertEquals(1, service.suchen("Mustermann").size()); // noch vorhanden
|
||||
}
|
||||
|
||||
@Test
|
||||
void finde_liefertAngelegtenKunden() { // K3
|
||||
long id = service.anlegen(gueltigerKunde());
|
||||
assertTrue(service.finde(id).isPresent());
|
||||
assertEquals(id, service.finde(id).get().getKundeId());
|
||||
assertTrue(service.finde(999L).isEmpty()); // unbekannte ID -> leer
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package de.hsmannheim.faktura.kunde.service;
|
||||
|
||||
import de.hsmannheim.faktura.kunde.model.Kunde;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class KundeValidatorTest {
|
||||
|
||||
private final KundeValidator validator = new KundeValidator();
|
||||
|
||||
private Kunde gueltigerKunde() {
|
||||
Kunde k = new Kunde();
|
||||
k.setNachname("Mustermann");
|
||||
k.setStrasse("Hauptstr. 1");
|
||||
k.setPlz("68159");
|
||||
k.setOrt("Mannheim");
|
||||
return k;
|
||||
}
|
||||
|
||||
@Test
|
||||
void gueltigerKunde_wirftNicht() {
|
||||
assertDoesNotThrow(() -> validator.pruefe(gueltigerKunde()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ohneFirmennameUndNachname_wirdAbgelehnt() { // → MT-KV-02
|
||||
Kunde k = gueltigerKunde();
|
||||
k.setNachname(null);
|
||||
assertThrows(ValidierungsException.class, () -> validator.pruefe(k));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ohneStrasse_wirdAbgelehnt() { // → MT-KV-03
|
||||
Kunde k = gueltigerKunde();
|
||||
k.setStrasse(null);
|
||||
assertThrows(ValidierungsException.class, () -> validator.pruefe(k));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ungueltigeEmail_wirdAbgelehnt() { // → MT-KV-04
|
||||
Kunde k = gueltigerKunde();
|
||||
k.setEmail("kunde@");
|
||||
assertThrows(ValidierungsException.class, () -> validator.pruefe(k));
|
||||
}
|
||||
|
||||
@Test
|
||||
void gueltigeEmail_wirftNicht() {
|
||||
Kunde k = gueltigerKunde();
|
||||
k.setEmail("kunde@example.com");
|
||||
assertDoesNotThrow(() -> validator.pruefe(k));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue