Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   DB Code und Unit Testen (https://www.delphipraxis.net/201706-db-code-und-unit-testen.html)

TurboMagic 18. Aug 2019 09:41

Datenbank: Firebird • Version: 2.5+ • Zugriff über: FireDAC

DB Code und Unit Testen
 
Hallo,

ich plane mittels FireDAC daten aus einer DB in Geschäftslogikklassen zu laden.
Die Daten werden dabei mehrheitlich als Listen gehalten werden.

Die Frage ist nun, wie trenne ich das Laden aus der DB so ab, dass ich die
Geschäftslogikklassen Unit Testen kann?

Eine Idee war der Geschäftslogikklasse die geöffnete FDQuery zu übergeben, da
diese Geschäftslogikklasse auch für den Aufbau der Liste zuständig sein soll
(da sie sonst wenig Funktionalität hat). Ich könnte mir an der Stelle vorstellen,
dass der Unit test eine FDQuery übergibt die auf eine InMemory Tabelle, was FireDAC
ja kann, zeigt in die ich die Test Daten vorher im setup des Unit Tests geschrieben
habe.

Ist das ein sinnvoller Weg?

Noch eine Frage: wenn ich in einer Schleife alle selektierten Datensätze auslesen
möchte um diese in die Datenstruktur im Speicher zu laden wäre es vermutlich nicht
so performant immer mittels FieldByName in jedem Schleifendurchlauf die jeweilige
Spalte und deren Wert anzusprechen. Oder? Welche Alternative gibt es zu FieldByName
die dann aber nicht gleich anfällig ist, wenn sich in der Struktur der DB Tabelle eine
Kleinigkeit ändert (z.B. Spalte zwischendrin hinzukommt oder wegfällt)?

Benutztes Delphi wird Rio sein.

Grüße
TurboMagic

Schokohase 18. Aug 2019 10:41

AW: DB Code und Unit Testen
 
Du solltest der Geschäftslogik-Klasse etwas Abstraktes übergeben um darüber die Daten zu laden.

z.B.
Delphi-Quellcode:
TMyData = record
  Id: Integer;
  Name: string;
end;

IDataProvider = interface
  function GetAllData() : TArray<TMyData>;
end;
In deiner Anwendung implementierst du dir da etwas mit einer Query-Komponente und fragst die Datenbank.
Für den Test nimmst du eine Mocking-Framework oder erstellst eine ganz simple Test-Implementierung die feste Werte zurück liefert.

Wenn eine Spalte in der Tabelle hinzukommt dann ist das egal, denn die Query
SQL-Code:
SELECT Id, Name FROM MyData
nimmt ja nur die Felder die sie abfragt.

Wenn du eine Spalte in der Tabelle entfernst, dann ist das auch egal, solange es keine Spalte ist, die abgefragt wird.

Aber das sollte ja auch logisch sein.

Uwe Raabe 18. Aug 2019 10:56

AW: DB Code und Unit Testen
 
Wenn deine Klassen oder die Laderoutine (wenn du die testen willst) ein DataSet erwarten, bietet sich ein MemoryTable an.

Über
Delphi-Quellcode:
FieldByName
brauchst du dir keine Gedanken machen, da dies seit einiger Zeit über ein Dictionary läuft und somit recht performant ist. Potentiell schneller wären nur direkte Feldvariablen oder der Zugriff über den Feldindex. Da muss man halt einen Kompromiss zwischen Schnelligkeit und Wartbarkeit des Code finden.

Der schöne Günther 18. Aug 2019 11:36

AW: DB Code und Unit Testen
 
Explizit eine Query ist schon ein bisschen hart, aber wenn es ein TDataSet bekommt ist da nichts verwerfliches dran. Ich hatte mal versucht ganz von der Verwendung eines TDataSet in der Anwendungslogik wegzukommen, aber da wurde man wirklich nicht mehr froh wenn man sich das ganze wie Lazy-Loading und alles selbst implementieren und neu erfinden muss.

Hauptsache deine Klassen arbeiten gegen Interfaces und keine konkreten Klassen. Dann kannst du in den Unit-Tests ja reinstecken was du willst. Ob es jetzt im SetUp() mittels Memory-Tables oder sonstwas aufgebaut wird ist dann ja auch egal.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz