→ Zurück zur KassenSichV-Übersicht
Vollständiger TSE-Mock-Provider ohne physische Hardware. Für Unit-Tests, CI/CD-Pipelines und Bondrucktests. Erzeugt deterministische SHA-256-basierte Testsignaturen (kein echtes ECDSA). Keine externen Abhängigkeiten.
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
pub fn TseMockNew(): int64;
// Gibt TseManager-Handle zurück (allokiert)
// Kein Konfigurationsparameter nötig — Mock akzeptiert alles
// Mit TseManagerFree() freigeben
var mgr: int64 := TseMockNew();
// Direkt verwendbar — keine Initialize()-Konfiguration nötig
Der Mock kann verschiedene Fehlersituationen simulieren, um die Fehlerbehandlung der Kassensoftware zu testen:
// Verbindungsfehler simulieren (TseProcessBeleg gibt success=0, code=503)
pub fn TseMockSetSimulateError(mgr: int64, on: int64): void;
// Timeout simulieren (TseProcessBeleg gibt success=0, code=408)
pub fn TseMockSetSimulateTimeout(mgr: int64, on: int64): void;
fn TestVerbindungsfehler(): void {
var mgr: int64 := TseMockNew();
TseMockSetSimulateError(mgr, 1); // Fehler einschalten
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
// s.success = 0, s.errorMsg = "Simulierter Verbindungsfehler..."
SigErgebnisFree(sig);
TseMockSetSimulateError(mgr, 0); // Fehler ausschalten
TseManagerFree(mgr);
}
// Aktueller Transaktionszähler (monoton steigend ab 0)
pub fn TseMockGetZaehler(mgr: int64): int64;
// TSE-Seriennummer des Mocks
pub fn TseMockGetSerial(mgr: int64): int64; // pchar, allokiert
Der Mock-Zähler startet bei 0 und steigt mit jedem erfolgreichen TseProcessBeleg / TseCloseBeleg um 1. Er kann in Tests für Assertions verwendet werden:
fn TestZaehlerMonoton(): void {
var mgr: int64 := TseMockNew();
// Erster Bon: Zähler wird 1
var b1: BelegDaten; b1.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig1: int64 := TseProcessBeleg(mgr, addr b1);
SigErgebnisFree(sig1);
// Zweiter Bon: Zähler wird 2
var b2: BelegDaten; b2.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig2: int64 := TseProcessBeleg(mgr, addr b2);
var s2: SigErgebnis := (sig2 as *SigErgebnis)^;
// s2.sigZaehler == 2 (immer höher als vorheriger)
SigErgebnisFree(sig2);
TseManagerFree(mgr);
}
Der Mock erzeugt Signaturen als SHA-256-Hash über (TransId + Zeitstempel-Millisekunden), Base64-kodiert. Das Ergebnis ist deterministisch für gleiche Eingaben, aber kryptografisch unsicher — nur für Tests geeignet.
Echte TSEs verwenden ECDSA/SHA-256 mit einem hardwaregeschützten Schlüssel (nicht aus dem Gerät extrahierbar).
Der Mock verwendet immer die feste Seriennummer:
MOCK-TSE-0000000000000001
In Tests, die die TSE-Seriennummer auf dem Bon prüfen, diesen Wert als Referenz verwenden.
TseExportAuditData mit dem Mock erstellt eine leere mock_audit.tar im Zielverzeichnis. Die Datei existiert, hat aber keinen Inhalt (Mock-Daten). Nützlich, um den Export-Workflow (Verzeichnis schreibbar, index.json vorhanden) ohne echte TSE zu testen.
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
fn TestKomplettprozess(): void {
var mgr: int64 := TseMockNew();
// --- Einfacher Bon ---
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "KASSE-001"c;
beleg.prozessDaten := "Kaffee;2.50_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 250;
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
// Prüfungen
// s.success == 1
// s.sigZaehler == 1
// s.qrCode beginnt mit "V0;MOCK-TSE-"
SigErgebnisFree(sig);
// --- Fehlersimulation ---
TseMockSetSimulateTimeout(mgr, 1);
var beleg2: BelegDaten; beleg2.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig2: int64 := TseProcessBeleg(mgr, addr beleg2);
var s2: SigErgebnis := (sig2 as *SigErgebnis)^;
// s2.success == 0
// s2.errorMsg enthält "Timeout"
SigErgebnisFree(sig2);
TseMockSetSimulateTimeout(mgr, 0);
TseManagerFree(mgr);
}
Letzte Aktualisierung: 2026-06-12