很多時候,開發人員嘗試測試 100%(或幾乎 100%)的程式碼。顯然,這是每個團隊應該為他們的專案達到的目標,但從我的角度來看,只應該完全測試整個程式碼的一部分:您的網域。
域基本上是程式碼中定義項目實際功能的部分。例如,當您將實體持久保存到資料庫時,您的網域不負責將其持久保存在資料庫上,而是確保持久性資料根據您的業務模型有意義。可能,當您將資料儲存到資料庫時,您將使用 PHP Doctrine 等外部函式庫。該庫已經經過充分測試,無需測試它的功能。如果您將正確的資料傳遞給學說,它將毫無問題地保存到資料庫中。
以下部分中顯示的範例並不試圖展示領域驅動設計是如何運作的,有很多文章對其進行了很好的解釋。我將嘗試展示如何明確定義和解耦您的網域可以幫助輕鬆測試並專注於您的應用程式的功能。
這個範例是在 Symfony 環境上建置並使用 PHPUnit 函式庫的,但這個想法對任何語言或框架都有效。
假設我們的應用程式連接到一個外部 API,該 API 傳回有關指定日期的下雨機率的資料。傳回的數據如下所示:
{ "date" : "2022-12-01", "rain_probability" : 0.75 }
現在,我們必須獲取這些數據並按照以下映射對其進行分類:
並將結果保存在由以下實體描述的資料庫表中:
#[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 // ....... }
讓我們建立一個處理程序,它獲取外部 api 數據,根據下雨機率設定標籤並將其保存到資料庫。
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 && $measureData['rain_probability'] setDate($measureData['date']); $rainMeasure->setProbability($measureData['rain_probability']); $rainMeasure->setLabel($label); $this->em->persist($rainMeasure); $this->em->flush(); } }
如果我們嘗試為上述處理程序建立一個測試,我們會發現我們需要注入EntityManagerInterface,因為我們想要測試的行為(根據機率值設定標籤)是耦合在同一個處理程序中,將結果儲存到資料庫中。我們可以嘗試使用類比和存根來載入 EntityManagerInterface,但有必要嗎?顯然不是。正如之前所說,我們應該嘗試專注於測試屬於我們領域的行為,即根據下雨機率獲得正確的標籤。
為了簡化我們的測試,我們將要測試的行為移至另一個類別:
class RainMeasureLabelHandler { public function getLabelFromProbability(float $prob): string { if($prob = 0.40 && $prob現在,我們的 RainMeassureHandler 將如下所示:
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(); } }現在我們可以專注於測試我們的RainMeasureLabelHandler,它將成為我們領域的一部分,並且不依賴外部層。測試它很簡單,如圖所示:
結論
我想說其他類型的測驗也很有用。也許我們有一個 api,並且希望使用一個測試環境來測試輸入和輸出,其中包括資料庫和我們可能需要的其他資源。但是,請記住將您的網域解耦並進行全面測試。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3