」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 將測試集中在網域上。 PHPUnit 範例

將測試集中在網域上。 PHPUnit 範例

發佈於2024-11-03
瀏覽:196

介紹

很多時候,開發人員嘗試測試 100%(或幾乎 100%)的程式碼。顯然,這是每個團隊應該為他們的專案達到的目標,但從我的角度來看,只應該完全測試整個程式碼的一部分:您的網域。

域基本上是程式碼中定義項目實際功能的部分。例如,當您將實體持久保存到資料庫時,您的網域不負責將其持久保存在資料庫上,而是確保持久性資料根據您的業務模型有意義。可能,當您將資料儲存到資料庫時,您將使用 PHP Doctrine 等外部函式庫。該庫已經經過充分測試,無需測試它的功能。如果您將正確的資料傳遞給學說,它將毫無問題地保存到資料庫中。

以下部分中顯示的範例並不試圖展示領域驅動設計是如何運作的,有很多文章對其進行了很好的解釋。我將嘗試展示如何明確定義和解耦您的網域可以幫助輕鬆測試並專注於您的應用程式的功能。

這個範例是在 Symfony 環境上建置並使用 PHPUnit 函式庫的,但這個想法對任何語言或框架都有效。

要測試的程式碼

假設我們的應用程式連接到一個外部 API,該 API 傳回有關指定日期的下雨機率的資料。傳回的數據如下所示:


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


現在,我們必須獲取這些數據並按照以下映射對其進行分類:

  • rain_probability 低
  • rain_probability ≥ 0.40 && rain_probability MEDIUM
  • 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,它將成為我們領域的一部分,並且不依賴外部層。測試它很簡單,如圖所示:

Focusing your tests on the domain. A PHPUnit example

結論

我想說其他類型的測驗也很有用。也許我們有一個 api,並且希望使用一個測試環境來測試輸入和輸出,其中包括資料庫和我們可能需要的其他資源。但是,請記住將您的網域解耦並進行全面測試。

版本聲明 本文轉載於:https://dev.to/icolomina/focusing-your-tests-on-the-domain-a-phpunit-example-c82?1如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • 模擬 Python 類別
    模擬 Python 類別
    最近,我必須使用 Pytest 為 Python 模組編寫單元測試。此模組包含一個類,其他類在其建構函數中初始化。 像往常一樣,我為此類創建了一個固定裝置,以便輕鬆為每個類別方法編寫測試。此時,當我嘗試模擬建構函數中啟動的不同類別時,我遇到了一些問題。模擬不起作用,這些類別的實例仍在建立中。 經...
    程式設計 發佈於2024-11-03
  • 如何在單一 MySQL 查詢中取得多筆記錄及其相關資料?
    如何在單一 MySQL 查詢中取得多筆記錄及其相關資料?
    在一個回應中傳回多個回應資料在您的PHP 程式碼中,您有一個從資料庫表中取得多行資料的查詢。但是,您收到多個回應,並且希望將它們合併為具有多個記錄的單一回應。 要實現此目的,您需要修改查詢以對必要的表執行左聯接。您將獲取主題數據並使用左連接包含相關學生信息,而不是獲取學生數據。這將允許您在單一回應中...
    程式設計 發佈於2024-11-03
  • D - 依賴倒置原理(DIP)
    D - 依賴倒置原理(DIP)
    Before understanding DIP (Dependency Inversion Principle), it's important to know what High-Level and Low-Level modules and abstractions are. ...
    程式設計 發佈於2024-11-03
  • 為什麼 JavaScript RegEx 無法驗證輸入?
    為什麼 JavaScript RegEx 無法驗證輸入?
    Javascript 中的RegEx 功能的鬥爭:“Regex 不工作”的案例研究在標題中引用的查詢的上下文中,“Javascript RegEx 不工作” ,」使用者遇到了一個問題,即無論輸入值如何,正則表達式(regEx) 始終返回false。查詢中提供的程式碼片段如下:function che...
    程式設計 發佈於2024-11-03
  • 如何對 Ajax 請求進行排序以實現最佳控制?
    如何對 Ajax 請求進行排序以實現最佳控制?
    對Ajax 請求進行排序迭代集合並對每個元素進行單獨的Ajax 呼叫時,必須控制順序以防止伺服器過載和瀏覽器凍結。雖然可以使用自訂迭代器,但還有更優雅的解決方案可用。 jQuery 1.5 在jQuery 1.5 及更高版本中,$.ajaxQueue() 插件利用$ .Deferred、$.queu...
    程式設計 發佈於2024-11-03
  • 如何為 DOM 元素產生精確的 CSS 路徑?
    如何為 DOM 元素產生精確的 CSS 路徑?
    以增強的精度從 DOM 元素檢索 CSS 路徑提供的函數嘗試為給定 DOM 元素生成 CSS 路徑。然而,它的輸出缺乏特異性,無法捕捉元素在其兄弟元素中的位置。為了解決這個問題,我們需要一個更複雜的方法。 改進的 CSS 路徑函數下面介紹的增強函數解決了原來的限制:var cssPath = fun...
    程式設計 發佈於2024-11-03
  • 如何將單一 Python 字典寫入具有精確標題和值行的 CSV 檔案?
    如何將單一 Python 字典寫入具有精確標題和值行的 CSV 檔案?
    探索將Python 字典寫入CSV 文件的細微差別您對將Python 字典無縫寫入CSV 文件的追求給您帶來了意想不到的挑戰。雖然您設想在作為標題的字典鍵和作為第二行的值之間進行清晰的劃分,但您目前的方法似乎還不夠。讓我們深入細節,解鎖解決方案。 問題在於方法的選擇。 DictWriter.writ...
    程式設計 發佈於2024-11-03
  • 如何處理 Go 中延遲函數的錯誤回傳值?
    如何處理 Go 中延遲函數的錯誤回傳值?
    處理Go 中返回值錯誤的延遲函數當返回變數的函數在沒有延遲的情況下被延遲時,gometalinter 和errcheck 正確地發出警告檢查其回傳的錯誤。這可能會導致未處理的錯誤和潛在的運行時問題。 處理這種情況的習慣用法不是推遲函數本身,而是將其包裝在另一個檢查返回值的函數中。這是一個例子:def...
    程式設計 發佈於2024-11-03
  • 為什麼程式設計師不能總是記住程式碼:背後的科學
    為什麼程式設計師不能總是記住程式碼:背後的科學
    如果您曾經想知道為什麼程式設計師很難回憶起他們編寫的確切程式碼,那麼您並不孤單。儘管花了數小時編碼,許多開發人員經常忘記細節。這並不是因為缺乏知識或經驗,而是因為工作本身的本質。讓我們來探究一下這種現象背後的原因。 程式設計的本質 透過記憶解決問題 這比僅僅記憶語法...
    程式設計 發佈於2024-11-03
  • 你並不孤單:在社群的支持下掌握 Python
    你並不孤單:在社群的支持下掌握 Python
    加入 Python 社群可取得:社群論壇:向經驗豐富的開發者取得支援和建議(如 Stack Overflow)。 Discord 伺服器:即時聊天室,提供即時支援與指導(如 Python Discord)。線上課程與研討會:來自專家的指導,涵蓋各種主題(如 Udemy 上的 Python NumPy...
    程式設計 發佈於2024-11-03
  • 學習夥伴
    學習夥伴
    聊天機器人介面,允許使用者輸入訊息並接收來自 GPT-3.5 語言模型的對話回應。 特徵 用於處理 HTTP 請求的基於 Flask 的 Web 伺服器。 呈現用作使用者介面的基本 HTML 模板 (chat.html)。 透過 POST 請求接受使用者輸入並將其傳送到 OpenAI 的 GP...
    程式設計 發佈於2024-11-03
  • 前端開發 + 資料結構與演算法:DSA 如何為您的 React 應用程式提供動力 ⚡
    前端開發 + 資料結構與演算法:DSA 如何為您的 React 應用程式提供動力 ⚡
    专注于前端的面试通常根本不关心 DSA。 对于我们这些记得在学校/大学学习过 DSA 的人来说,所有的例子都感觉纯粹是算法(有充分的理由),但几乎没有任何例子或指导来说明我们每天使用的产品如何利用这个概念。 “我需要这个吗?” 你已经问过很多次这个问题了,不是吗? ? 以下是您今天可以在 React...
    程式設計 發佈於2024-11-03
  • 為什麼表格行上的框陰影在不同瀏覽器中表現不同?
    為什麼表格行上的框陰影在不同瀏覽器中表現不同?
    跨瀏覽器表行上的框陰影外觀不一致應用於表行() 的CSS 框陰影可能表現出不一致的行為跨各種瀏覽器。儘管 CSS 相同,但某些瀏覽器可能會如預期顯示陰影,而其他瀏覽器則可能不會。 要解決此問題,建議將 Transform 屬性與 box-shadow 屬性結合使用。將scale(1,1)加入tran...
    程式設計 發佈於2024-11-03
  • 探索 PHP 中的並發性和並行性:實作教學和技巧
    探索 PHP 中的並發性和並行性:實作教學和技巧
    理解並發性和平行性對於編寫高效的 PHP 應用程式至關重要,特別是在處理需要同時處理的多個任務或操作時。這是理解和實作 PHP 並發性和平行性的逐步指南,包含實作範例和說明。 1.併發與並行 並發:指系統透過交錯執行同時處理多個任務的能力。這並不一定意味著任務是同時執行的,只是對它...
    程式設計 發佈於2024-11-03
  • ReactJs 與 Angular
    ReactJs 與 Angular
    React 和 Angular 是用于构建 Web 应用程序的两个最流行的框架/库,但它们在关键方面有所不同。以下是 React 和 Angular 之间主要区别的细分: 1. 类型:库与框架 React:一个用于构建用户界面的库,主要关注视图层。它允许开发人员将其与其他库集成以处理...
    程式設計 發佈於2024-11-03

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3