Konzentrieren Sie Ihre Tests auf die Domäne. Ein PHPUnit-Beispiel

DDD
Freigeben: 2024-10-05 06:07:30
Original
605 Leute haben es durchsucht

Einführung

Oft versuchen Entwickler, 100 % (oder fast 100 %) ihres Codes zu testen. Anscheinend ist dies das Ziel, das jedes Team für seine Projekte erreichen sollte, aber aus meiner Sicht sollte nur ein Teil des gesamten Codes vollständig getestet werden: Ihre Domain.

Die Domäne ist im Grunde der Teil Ihres Codes, der definiert, was das Projekt tatsächlich tut. Wenn Sie beispielsweise eine Entität in der Datenbank beibehalten, ist Ihre Domäne nicht dafür verantwortlich, sie in der Datenbank beizubehalten, sondern dafür zu sorgen, dass die beibehaltenen Daten für Ihr Geschäftsmodell sinnvoll sind. Wenn Sie Ihre Daten in der Datenbank speichern, verwenden Sie möglicherweise eine externe Bibliothek wie PHP Doctrine. Diese Bibliothek ist bereits vollständig getestet, es besteht keine Notwendigkeit, ihre Funktion zu testen. Wenn Sie die richtigen Daten an doctrine übergeben, werden diese ohne Probleme in der Datenbank gespeichert.

Das in den folgenden Abschnitten gezeigte Beispiel versucht nicht zu zeigen, wie das Domain Driven Design funktioniert, es gibt viele Artikel, die es sehr gut erklären. Ich werde versuchen zu zeigen, wie eine gut definierte und entkoppelte Domain dazu beitragen kann, einfach zu testen und sich auf die Funktionsweise Ihrer Anwendung zu konzentrieren.

Das Beispiel basiert auf einer Symfony-Umgebung und unter Verwendung der PHPUnit-Bibliothek, aber die Idee ist für jede Sprache und jedes Framework gültig.

Der zu testende Code

Stellen wir uns vor, dass unsere Anwendung eine Verbindung zu einer externen API herstellt, die Daten über die Regenwahrscheinlichkeit für ein bestimmtes Datum zurückgibt. Die zurückgegebenen Daten sehen folgendermaßen aus:


{
   "date" : "2022-12-01",
   "rain_probability" : 0.75
}


Nach dem Login kopieren

Jetzt müssen wir diese Daten nehmen und sie gemäß dieser Zuordnung klassifizieren:

  • Regenwahrscheinlichkeit < 0,40: NIEDRIG
  • Regenwahrscheinlichkeit ≥ 0,40 && Regenwahrscheinlichkeit < 0,75: MITTEL
  • Regenwahrscheinlichkeit ≥ 0,75: HOCH

und speichern Sie das Ergebnis in einer Datenbanktabelle, die durch die folgende Entität beschrieben wird:


#[ORM\Entity(repositoryClass: RainMeasure::class)]
class RainMeasure {

    #[ORM\Column]
    private string $date;

    #[ORM\Column]
    private float $probability;

    #[ORM\Column(length: 10)]
    private string $label;

    // Getters and setters
    // .......
}


Nach dem Login kopieren

Lassen Sie uns einen Handler erstellen, der die externen API-Daten abruft, die Beschriftung entsprechend der Regenwahrscheinlichkeit festlegt und sie in der Datenbank speichert.


class RainMeassureHandler {
    private EntityManagerInterface $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function saveMeasure(array $measureData): void
    {
        if($measureData['rain_probability'] < 0.40){
            $label = 'LOW';
        }
        elseif ($measureData['rain_probability'] >= 0.40 && $measureData['rain_probability'] < 0.75){
            $label = 'MEDIUM';
        }
        else{
            $label = 'HIGH';
        }

        $rainMeasure = new RainMeassure();
        $rainMeasure->setDate($measureData['date']);
        $rainMeasure->setProbability($measureData['rain_probability']);
        $rainMeasure->setLabel($label);

        $this->em->persist($rainMeasure);
        $this->em->flush();
    }
}




<p>Wenn wir versuchen, einen Test für den oben genannten Handler zu erstellen, werden wir feststellen, dass wir das <strong>EntityManagerInterface</strong> einfügen müssen, da das Verhalten, das wir testen möchten (Festlegen einer Bezeichnung entsprechend dem Wahrscheinlichkeitswert), ist im selben Handler gekoppelt, der das Ergebnis in der Datenbank speichert. Wir könnten versuchen, das <strong>EntityManagerInterface</strong> mithilfe von Mocks und Stubs zu laden, aber ist das notwendig? Offensichtlich nicht. Wie bereits erwähnt, sollten wir versuchen, uns auf das Testen des Verhaltens zu konzentrieren, das zu unserer Domäne gehört, nämlich das Erhalten der richtigen Bezeichnung entsprechend der Regenwahrscheinlichkeit.</p>

<h2>
  
  
  Entkopplungsverhalten wollen wir testen
</h2>

<p>Um unseren Test zu vereinfachen, verschieben wir das Verhalten, das wir testen möchten, in eine andere Klasse:</p>

<pre class="brush:php;toolbar:false">

class RainMeasureLabelHandler 
{
    public function getLabelFromProbability(float $prob): string
    {
        if($prob < 0.40){
            $label = 'LOW';
        }
        elseif ($prob >= 0.40 && $prob < 0.75){
            $label = 'MEDIUM';
        }
        else{
            $label = 'HIGH';
        }

        return $label;
    }
}


Nach dem Login kopieren

Und jetzt sieht unser RainMeassureHandler so aus:


class RainMeasureHandler 
{
    private EntityManagerInterface $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function saveMeasure(array $measureData): void
    {
        $rainMeasureLabelHandler = new RainMeasureLabelHandler();
        $label = $rainMeasureLabelHandler->getLabelFromProbability($measureData['rain_probability']);

        $rainMeasure = new RainMeasure();
        $rainMeasure->setDate($measureData['date']);
        $rainMeasure->setProbability($measureData['rain_probability']);
        $rainMeasure->setLabel($label);

        $this->em->persist($rainMeasure);
        $this->em->flush();
    }
}


Nach dem Login kopieren

Jetzt können wir uns darauf konzentrieren, unseren RainMeasureLabelHandler zu testen, der Teil unserer Domäne wäre und keine Abhängigkeiten von externen Ebenen hätte. Das Testen wäre so einfach wie gezeigt:

Focusing your tests on the domain. A PHPUnit example

Abschluss

Ich möchte sagen, dass auch andere Arten von Tests nützlich wären. Vielleicht haben wir eine API und möchten Eingaben und Ausgaben mit einer Testumgebung testen, die Datenbanken und andere Ressourcen enthält, die wir möglicherweise benötigen. Denken Sie jedoch daran, Ihre Domain zu entkoppeln und vollständig zu testen.

Das obige ist der detaillierte Inhalt vonKonzentrieren Sie Ihre Tests auf die Domäne. Ein PHPUnit-Beispiel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!