Refactor code structure for improved readability and maintainability
parent
77e3ec2a33
commit
7ec671d157
|
|
@ -0,0 +1,50 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Projekt
|
||||||
|
|
||||||
|
Desktop-Fakturierungsanwendung (Einzelplatz) für ein Hochschulprojekt (SE1, Team 1). Java 21, Swing-GUI mit FlatLaf, Maven-Build. Alle Texte (Klassen, Methoden, Variablen, Kommentare, Spezifikationen) sind auf **Deutsch**.
|
||||||
|
|
||||||
|
## Build & Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./mvnw compile # Kompilieren
|
||||||
|
./mvnw test # Alle Tests (JUnit 5)
|
||||||
|
./mvnw test -Dtest=KundenVerwaltungTest # Einzelne Testklasse
|
||||||
|
./mvnw test -Dtest=KundenVerwaltungTest#testMethode # Einzelne Testmethode
|
||||||
|
./mvnw package # Fat-JAR bauen (maven-shade-plugin)
|
||||||
|
java -jar target/fakturierung-1.0.0.jar # Anwendung starten
|
||||||
|
```
|
||||||
|
|
||||||
|
## PDF-Spezifikationen bauen
|
||||||
|
|
||||||
|
Die `*.md`-Dateien im Wurzelverzeichnis (Lastenheft, Pflichtenheft_Gruppe{A-D}, Modultestplan) werden mit pandoc + XeLaTeX zu PDF konvertiert — es gibt kein Build-Skript, der Aufruf erfolgt manuell.
|
||||||
|
|
||||||
|
## Diagramme
|
||||||
|
|
||||||
|
PlantUML-Quelldateien liegen in `diagramme/`. Rendering via `tools/plantuml.jar`.
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
|
||||||
|
Vier fachliche Module, jeweils einer Projektgruppe zugeordnet:
|
||||||
|
|
||||||
|
| Paket | Gruppe | Verantwortung |
|
||||||
|
|-------|--------|---------------|
|
||||||
|
| `dokumente` | A | Dokumentenzyklus: Angebot → Auftragsbestätigung → Lieferschein → Rechnung, Belegnummern, PDF-Export |
|
||||||
|
| `produkte` | B | Produktverwaltung (CRUD, Nummernvergabe, Löschsperre) |
|
||||||
|
| `kunden` | C | Kundenverwaltung (CRUD, Nummernvergabe, Löschsperre) |
|
||||||
|
| `gui` | D | Swing-Oberfläche (HauptFenster, Panels, Dialoge, Wizard) |
|
||||||
|
| `gemeinsam` | — | Querschnitt: EreignisBus, JsonPersistenz, CSV-Hilfe, Exceptions |
|
||||||
|
|
||||||
|
### Wichtige Muster
|
||||||
|
|
||||||
|
- **EreignisBus** (Observer): Services melden Datenänderungen (`DatenBereich.KUNDEN/PRODUKTE/DOKUMENTE`), GUI-Panels abonnieren und aktualisieren sich. Kein manueller Refresh nötig.
|
||||||
|
- **Repository-Interfaces** (`KundenRepository`, `ProduktRepository`, `DokumentRepository`) mit JSON-Implementierungen. Persistenz erfolgt atomar via `JsonPersistenz.schreibeAtomar()`.
|
||||||
|
- **NummernGenerator-Interfaces** (`KundennummernGenerator`, `ProduktnummernGenerator`, `BelegnummernGenerator`) mit `Einfacher*`-Implementierungen, die den nächsten Wert aus dem Repository-Bestand ableiten.
|
||||||
|
- **ReferenzPrüfung**: `DokumentReferenzPruefung` verhindert Löschung von Kunden/Produkten, die in Dokumenten referenziert werden.
|
||||||
|
- **Wiring** in `Main.java`: Manuelle Dependency Injection — kein Framework.
|
||||||
|
|
||||||
|
### Persistenz
|
||||||
|
|
||||||
|
Alle Daten liegen als JSON-Dateien im Verzeichnis `daten/` (kunden.json, produkte.json, dokumente.json). Dieses Verzeichnis ist in `.gitignore`.
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
---
|
||||||
|
marp: true
|
||||||
|
theme: default
|
||||||
|
paginate: true
|
||||||
|
lang: de
|
||||||
|
header: 'Team 1 · Desktop-Fakturierungsanwendung'
|
||||||
|
footer: 'Abschlusspräsentation · Software Engineering 1 · 29.06.2026'
|
||||||
|
style: |
|
||||||
|
section {
|
||||||
|
font-size: 26px;
|
||||||
|
padding: 60px 70px;
|
||||||
|
color: #1f2933;
|
||||||
|
}
|
||||||
|
h1 { color: #16466b; }
|
||||||
|
h2 { color: #16466b; border-bottom: 3px solid #d9a441; padding-bottom: 6px; }
|
||||||
|
h3 { color: #2a6f97; }
|
||||||
|
strong { color: #16466b; }
|
||||||
|
table { font-size: 22px; }
|
||||||
|
th { background: #16466b; color: #fff; }
|
||||||
|
tr:nth-child(even) { background: #f2f5f8; }
|
||||||
|
code { background: #eef2f6; color: #16466b; }
|
||||||
|
section.lead { justify-content: center; text-align: center; }
|
||||||
|
section.lead h1 { font-size: 52px; }
|
||||||
|
section.divider {
|
||||||
|
background: #16466b; color: #fff; justify-content: center;
|
||||||
|
}
|
||||||
|
section.divider h1, section.divider h2 { color: #fff; border: none; }
|
||||||
|
section.divider h3 { color: #d9a441; }
|
||||||
|
footer, header { color: #8a98a5; }
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
<!-- _paginate: false -->
|
||||||
|
|
||||||
|
# Desktop-Fakturierungsanwendung
|
||||||
|
|
||||||
|
### Schlanke, lokal betriebene Fakturierung für Kleinstunternehmen
|
||||||
|
|
||||||
|
**Abschlusspräsentation · Software Engineering 1 (SoSe 2026)**
|
||||||
|
**Team 1**
|
||||||
|
|
||||||
|
29.06.2026 · Prof. Dr. Gerd Marmitt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agenda
|
||||||
|
|
||||||
|
1. **Team & Aufgabenverteilung**
|
||||||
|
2. **Kontext & Ziel** des Projekts
|
||||||
|
3. **Architektur** im Überblick
|
||||||
|
4. **Live-Demo** des Programms *(≈ 10 Min)*
|
||||||
|
5. **Entwicklungsprojekt** *(≈ 5 Min)*
|
||||||
|
- Ergebnisse der Modultestpläne
|
||||||
|
- Wo wurde KI eingesetzt – und wie gut?
|
||||||
|
- Was würden wir nächstes Mal anders machen?
|
||||||
|
6. **Fragen** *(5 Min)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Team & Aufgabenverteilung
|
||||||
|
|
||||||
|
12 Personen, vier fachliche Komponenten (V-Modell, Einzelplatzanwendung):
|
||||||
|
|
||||||
|
| Gruppe | Komponente | Leitung | Mitglieder |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **A** | Prozess / Dokumentenzyklus | Lucas Strubel | Luca Kaiser |
|
||||||
|
| **B** | Produktverwaltung | Meron Berhane | Jan-Micah SchulzeAmeling · Jessica Volz |
|
||||||
|
| **C** | Kundenverwaltung | Mahsuna Ahadyar | Kübra Kilic · Mara Weidmann |
|
||||||
|
| **D** | Programmoberfläche | Mirkan Güngör | Moritz König · Mohammed Bouhki |
|
||||||
|
|
||||||
|
Querschnitt (`gemeinsam`): EreignisBus, JSON-Persistenz, CSV-Hilfe – von allen Gruppen genutzt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kontext & Ziel
|
||||||
|
|
||||||
|
**Problem:** SaaS-Fakturierung kostet laufend Lizenzgebühren; Open-Source-Alternativen (z. B. *Fakturama*) sind im Betrieb anspruchsvoll.
|
||||||
|
|
||||||
|
**Unsere Lösung:** schlanke Desktop-Anwendung mit voller Datensouveränität – ohne Cloud.
|
||||||
|
|
||||||
|
| Ziel | Inhalt |
|
||||||
|
|---|---|
|
||||||
|
| **PZ-01** | Digitale Verwaltung von Kunden- & Produktstammdaten (CRUD) |
|
||||||
|
| **PZ-02** | Vollständiger Dokumentenzyklus: Angebot → AB → Lieferschein → Rechnung |
|
||||||
|
| **PZ-03** | Bedienbar ohne Vorkenntnisse (Rechnung in < 10 Min) |
|
||||||
|
| **PZ-04** | 100 % lokale, DSGVO-konforme Datenhaltung |
|
||||||
|
|
||||||
|
*Nichtziele:* Mehrbenutzer/Netzwerk, vollständige Buchhaltung, E-Rechnung (ZUGFeRD/XRechnung).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architektur im Überblick
|
||||||
|
|
||||||
|
**Vier Fachmodule + gemeinsame Infrastruktur**, manuelle Dependency Injection in `Main.java` (kein Framework).
|
||||||
|
|
||||||
|
- **Repository-Interfaces** je Domäne mit JSON-Implementierungen; atomare Schreibvorgänge (`JsonPersistenz.schreibeAtomar`)
|
||||||
|
- **EreignisBus** (Observer): Services melden Datenänderungen, GUI-Panels aktualisieren sich selbst
|
||||||
|
- **Snapshot-Prinzip** in Belegen + **Löschsperren** (referenzielle Integrität)
|
||||||
|
|
||||||
|
**Technologie-Stack**
|
||||||
|
|
||||||
|
`Java 21` · `Swing + FlatLaf 3.6` · `Maven` (Fat-JAR via shade) · `Jackson 2.17` (JSON) · `Apache PDFBox 3.0` (PDF) · `JUnit 5.10`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: divider -->
|
||||||
|
<!-- _paginate: false -->
|
||||||
|
|
||||||
|
# Live-Demo
|
||||||
|
### Das entwickelte Programm
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Demo 1 — Stammdaten
|
||||||
|
|
||||||
|
**Kundenverwaltung (Gruppe C)**
|
||||||
|
- Anlegen mit eindeutiger Kundennummer (`K-000017`), Pflichtfeld-Validierung *(BA-01)*
|
||||||
|
- Suchen & sortierte Liste, Ändern *(BA-02, BA-04)*
|
||||||
|
- **Löschsperre**: Kunde mit verknüpften Dokumenten wird nicht gelöscht *(BA-03, GR-04)*
|
||||||
|
|
||||||
|
**Produktverwaltung (Gruppe B)**
|
||||||
|
- Anlegen mit Nettopreis & zulässigem Steuersatz, Nummernvergabe `P-000042` *(BA-05)*
|
||||||
|
- Ändern, Suche, **Löschsperre** bei referenzierten Produkten *(BA-06–BA-08)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Demo 2 — Dokumentenzyklus (Gruppe A)
|
||||||
|
|
||||||
|
**Angebot → Auftragsbestätigung → Lieferschein → Rechnung**
|
||||||
|
|
||||||
|
- Folgebeleg übernimmt Kunde, Positionen & Mengen und speichert eine **Rückreferenz** *(GR-05)*
|
||||||
|
- **Lückenlose** Belegnummern `R-2026-000124` (GoBD) *(GR-01)*
|
||||||
|
- Automatische **Steuerberechnung** netto / Steuer / brutto, Scale 2 *(GR-03)*
|
||||||
|
- Standard-**Zahlungsziel** +14 Tage, falls nicht angegeben *(GR-06)*
|
||||||
|
- Rechnung mit allen Pflichtangaben gem. **§ 14 UStG** *(BA-12)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Demo 3 — Wizard, Export & Storno
|
||||||
|
|
||||||
|
- **Geführte Rechnungserstellung** (Wizard): Kunde → Positionen → Bestätigen → Zusammenfassung → Speichern *(BA-13)*
|
||||||
|
- **PDF-Export** der Belege (PDFBox) ins lokale Dateisystem *(IF-01)*
|
||||||
|
- **CSV-Vollexport** von Stamm- **und** Bewegungsdaten – offenes Format *(Q-08)*
|
||||||
|
- **Stornierung** einer offenen Rechnung mit Datum & Benutzer; versendete Belege sind **unveränderlich** *(BA-14, GR-02)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: divider -->
|
||||||
|
<!-- _paginate: false -->
|
||||||
|
|
||||||
|
# Das Entwicklungsprojekt
|
||||||
|
### Modultests · KI-Einsatz · Lessons Learned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ergebnisse der Modultestpläne
|
||||||
|
|
||||||
|
**71 deterministische JUnit-5-Testfälle – alle grün.** Nachbarkomponenten durch Stubs/Mocks ersetzt.
|
||||||
|
|
||||||
|
| Komponente | Testfälle |
|
||||||
|
|---|---|
|
||||||
|
| A — Dokumentenzyklus (Zyklus, Persistenz, PDF, CSV) | 18 |
|
||||||
|
| B — Produktverwaltung | 14 |
|
||||||
|
| C — Kundenverwaltung | 14 |
|
||||||
|
| D — Programmoberfläche (Controller) | 15 |
|
||||||
|
| Gemeinsame Infrastruktur (EreignisBus, JSON) | 6 |
|
||||||
|
| Performance/Last (Q-02/03/04/08) | 4 |
|
||||||
|
| **Summe** | **71** |
|
||||||
|
|
||||||
|
Performance-Schranken eingehalten: Start ≤ 5 s, Suche ≤ 1 s, PDF ≤ 2 s, Export ≤ 30 s (5.000 Kunden/Produkte).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Traceability
|
||||||
|
|
||||||
|
**Lückenlose Kette: Anforderung → Codebeleg → Testfall.**
|
||||||
|
|
||||||
|
- Spezifikation der Testfälle: **`Modultestplan.md`** (Vorbedingung / Eingabe / erwartetes Ergebnis)
|
||||||
|
- Nachweismatrix: **`Anforderungsabgleich.md`** — BA-01…14, GR-01…06, Q-01…09, AC-01…11
|
||||||
|
- Jede Testfall-ID ist auch im Code per `@DisplayName` auffindbar
|
||||||
|
(`TC-…`, `INF-…`, `Q-…`) → direkt grep-bar
|
||||||
|
|
||||||
|
> Alle durch Code/Tests belegbaren Anforderungen sind ✅; offen bleiben nur organisatorische Usability-Tests (Q-05/AC-11).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wo wurde KI eingesetzt – und wie gut?
|
||||||
|
|
||||||
|
> *Entwurf — vom Team mit eigenen Erfahrungswerten zu ergänzen.*
|
||||||
|
|
||||||
|
**Eingesetzt für**
|
||||||
|
- **Dokumentation:** Entwürfe für Lasten-/Pflichtenhefte, Modultestplan, Traceability-Matrix
|
||||||
|
- **Code:** Boilerplate der Repository-/Service-Schicht, JSON-Persistenz, CSV-Export, JUnit-Testgerüste
|
||||||
|
- **Diagramme & Tooling:** PlantUML-Quellen, Maven-Konfiguration, pandoc-/PDF-Workflow
|
||||||
|
|
||||||
|
**Bewertung**
|
||||||
|
- 👍 Hohes Tempo bei wiederkehrendem Code, Tests & Doku; konsistente deutsche Fachsprache; schnelle Iteration nach Feedback
|
||||||
|
- 👎 Fachlogik (§ 14 UStG, GoBD, Steuer-/Snapshot-Regeln) und Gruppen-Schnittstellen mussten **manuell geprüft & nachgeschärft** werden; Vorschläge teils zu generisch
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Was würden wir nächstes Mal anders machen?
|
||||||
|
|
||||||
|
> *Entwurf — vom Team zu ergänzen.*
|
||||||
|
|
||||||
|
- **Früher integrieren:** modulübergreifende Tests nicht erst spät im V-Modell
|
||||||
|
- **Schnittstellen-Verträge** zwischen Gruppen A–D verbindlich zu Projektbeginn festlegen
|
||||||
|
- **Kleinere, häufigere Commits** + konsequentere Pull-Request-Reviews
|
||||||
|
- **KI-Output gezielter prüfen** statt übernehmen – besonders bei Fachlogik
|
||||||
|
- Aufgaben-/Lastverteilung über die Git-History früh sichtbar machen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Zusammenfassung
|
||||||
|
|
||||||
|
- Vollständiger **Dokumentenzyklus** + **Stammdatenverwaltung** lauffähig umgesetzt
|
||||||
|
- **Lokale, DSGVO-konforme** Einzelplatzanwendung (Java 21, Swing/FlatLaf)
|
||||||
|
- **71 grüne Modultests** mit vollständiger **Traceability** zu den Anforderungen
|
||||||
|
- Alle Performance-Anforderungen erfüllt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
<!-- _paginate: false -->
|
||||||
|
|
||||||
|
# Vielen Dank!
|
||||||
|
|
||||||
|
### Fragen?
|
||||||
|
|
||||||
|
**Team 1 · Desktop-Fakturierungsanwendung · SE1 SoSe 2026**
|
||||||
Binary file not shown.
|
|
@ -23,7 +23,7 @@ class DokumentCsvExportTest {
|
||||||
Path tempDir;
|
Path tempDir;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Q-08: Export schreibt Kopfzeile und je eine Zeile pro Dokumentposition")
|
@DisplayName("TC-18 (Q-08): Export schreibt Kopfzeile und je eine Zeile pro Dokumentposition")
|
||||||
void exportiertAlleBelegeMitPositionen() throws IOException {
|
void exportiertAlleBelegeMitPositionen() throws IOException {
|
||||||
JsonDokumentRepository repository = new JsonDokumentRepository(tempDir.resolve("dokumente.json"));
|
JsonDokumentRepository repository = new JsonDokumentRepository(tempDir.resolve("dokumente.json"));
|
||||||
repository.speichere(TestBelege.rechnung("R-2026-000001", DokumentStatus.OFFEN));
|
repository.speichere(TestBelege.rechnung("R-2026-000001", DokumentStatus.OFFEN));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class JsonDokumentRepositoryTest {
|
||||||
Path tempDir;
|
Path tempDir;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Belege überleben den Neustart und behalten ihren Belegtyp")
|
@DisplayName("TC-14: Belege überleben den Neustart und behalten ihren Belegtyp")
|
||||||
void belegeWerdenNachNeustartGeladen() {
|
void belegeWerdenNachNeustartGeladen() {
|
||||||
Path datei = tempDir.resolve("dokumente.json");
|
Path datei = tempDir.resolve("dokumente.json");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class PdfBoxPdfExporterTest {
|
||||||
Path tempDir;
|
Path tempDir;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Vollständiger Beleg wird als PDF-Datei exportiert")
|
@DisplayName("TC-15: Vollständiger Beleg wird als PDF-Datei exportiert")
|
||||||
void exportiertVollstaendigenBeleg() {
|
void exportiertVollstaendigenBeleg() {
|
||||||
Path ziel = tempDir.resolve("rechnung.pdf");
|
Path ziel = tempDir.resolve("rechnung.pdf");
|
||||||
Rechnung rechnung = TestBelege.rechnung("R-2026-000001", DokumentStatus.OFFEN);
|
Rechnung rechnung = TestBelege.rechnung("R-2026-000001", DokumentStatus.OFFEN);
|
||||||
|
|
@ -35,7 +35,7 @@ class PdfBoxPdfExporterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Altdaten mit null-Positionsfeldern werfen beim Export keinen Fehler")
|
@DisplayName("TC-16: Altdaten mit null-Positionsfeldern werfen beim Export keinen Fehler")
|
||||||
void exportiertBelegMitNullPositionsfeldern() {
|
void exportiertBelegMitNullPositionsfeldern() {
|
||||||
Path ziel = tempDir.resolve("altdaten.pdf");
|
Path ziel = tempDir.resolve("altdaten.pdf");
|
||||||
Rechnung rechnung = new Rechnung();
|
Rechnung rechnung = new Rechnung();
|
||||||
|
|
@ -49,7 +49,7 @@ class PdfBoxPdfExporterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Summenberechnung behandelt null-Positionssummen als 0")
|
@DisplayName("TC-17: Summenberechnung behandelt null-Positionssummen als 0")
|
||||||
void summenberechnungToleriertNullPositionen() {
|
void summenberechnungToleriertNullPositionen() {
|
||||||
Rechnung rechnung = new Rechnung();
|
Rechnung rechnung = new Rechnung();
|
||||||
rechnung.setBelegnummer("R-2026-000098");
|
rechnung.setBelegnummer("R-2026-000098");
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
class EreignisBusTest {
|
class EreignisBusTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("melde benachrichtigt alle Beobachter des Bereichs")
|
@DisplayName("INF-01: melde benachrichtigt alle Beobachter des Bereichs")
|
||||||
void benachrichtigtAlleBeobachter() {
|
void benachrichtigtAlleBeobachter() {
|
||||||
EreignisBus bus = new EreignisBus();
|
EreignisBus bus = new EreignisBus();
|
||||||
AtomicInteger ersterBeobachter = new AtomicInteger();
|
AtomicInteger ersterBeobachter = new AtomicInteger();
|
||||||
|
|
@ -26,7 +26,7 @@ class EreignisBusTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("melde benachrichtigt nur Beobachter des betroffenen Bereichs")
|
@DisplayName("INF-02: melde benachrichtigt nur Beobachter des betroffenen Bereichs")
|
||||||
void benachrichtigtNurBetroffenenBereich() {
|
void benachrichtigtNurBetroffenenBereich() {
|
||||||
EreignisBus bus = new EreignisBus();
|
EreignisBus bus = new EreignisBus();
|
||||||
AtomicInteger kundenBeobachter = new AtomicInteger();
|
AtomicInteger kundenBeobachter = new AtomicInteger();
|
||||||
|
|
@ -41,7 +41,7 @@ class EreignisBusTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("melde ohne Beobachter ist wirkungslos und wirft nicht")
|
@DisplayName("INF-03: melde ohne Beobachter ist wirkungslos und wirft nicht")
|
||||||
void meldenOhneBeobachterIstWirkungslos() {
|
void meldenOhneBeobachterIstWirkungslos() {
|
||||||
new EreignisBus().melde(DatenBereich.PRODUKTE);
|
new EreignisBus().melde(DatenBereich.PRODUKTE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class JsonPersistenzTest {
|
||||||
private final ObjectMapper mapper = JsonPersistenz.mapper();
|
private final ObjectMapper mapper = JsonPersistenz.mapper();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("schreibeAtomar legt die Zieldatei an und lässt keine Temp-Datei zurück")
|
@DisplayName("INF-04: schreibeAtomar legt die Zieldatei an und lässt keine Temp-Datei zurück")
|
||||||
void schreibtOhneTempDateiRueckstand(@TempDir Path verzeichnis) throws IOException {
|
void schreibtOhneTempDateiRueckstand(@TempDir Path verzeichnis) throws IOException {
|
||||||
Path datei = verzeichnis.resolve("bestand.json");
|
Path datei = verzeichnis.resolve("bestand.json");
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ class JsonPersistenzTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("schreibeAtomar ersetzt einen vorhandenen Bestand vollständig")
|
@DisplayName("INF-05: schreibeAtomar ersetzt einen vorhandenen Bestand vollständig")
|
||||||
void ersetztVorhandenenBestand(@TempDir Path verzeichnis) throws IOException {
|
void ersetztVorhandenenBestand(@TempDir Path verzeichnis) throws IOException {
|
||||||
Path datei = verzeichnis.resolve("bestand.json");
|
Path datei = verzeichnis.resolve("bestand.json");
|
||||||
JsonPersistenz.schreibeAtomar(datei, mapper.writer(), List.of("alt"));
|
JsonPersistenz.schreibeAtomar(datei, mapper.writer(), List.of("alt"));
|
||||||
|
|
@ -45,7 +45,7 @@ class JsonPersistenzTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("schreibeAtomar legt fehlende Elternverzeichnisse an")
|
@DisplayName("INF-06: schreibeAtomar legt fehlende Elternverzeichnisse an")
|
||||||
void legtElternverzeichnisseAn(@TempDir Path verzeichnis) throws IOException {
|
void legtElternverzeichnisseAn(@TempDir Path verzeichnis) throws IOException {
|
||||||
Path datei = verzeichnis.resolve("unterordner").resolve("bestand.json");
|
Path datei = verzeichnis.resolve("unterordner").resolve("bestand.json");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue