模擬 Python 類別

王林
發布: 2024-08-28 18:32:30
原創
371 人瀏覽過

Mocking Python Classes

最近,我必須使用 Pytest 為 Python 模組編寫單元測試。此模組包含一個類,其他類在其建構函數中初始化。

像往常一樣,我為此創建了一個固定裝置,以便輕鬆為每個類別方法編寫測試。此時,當我嘗試模擬建構函數中啟動的不同類別時,我遇到了一些問題。模擬不起作用,這些類別的實例仍在建立中。

經過一些研究並結合我在網路上找到的一些不同的解決方案,我想分享我如何成功模擬課程。

解決方案

這是我嘗試模擬的類別的範例:

class ClassA:
    def __init__(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0
登入後複製

我們希望在測試期間為此類的每個欄位設定一個值。該值可以是 None 或類別模擬,但我們不希望啟動 ClassB 和 ClassC 類別。

在我們的例子中,讓我們決定 self.class_b 和 self.class_c 應該是模擬:

@pytest.fixture
def mock_class_b():
    class_b = Mock(spec=ClassB)
    return class_b

@pytest.fixture
def mock_class_c():
    class_c = Mock(spec=ClassC)
    return class_c
登入後複製

因此,為我們的目標提供服務的此類固定裝置如下所示:

@pytest.fixture
def class_a_mock(mock_class_b, mock_class_c):
    with patch.object(target=ClassA, attribute="__init__", return_value=None) as mock_init:
        class_a = ClassA()
        class_a.class_b = mock_class_b
        class_a.class_c = mock_class_c
        class_b.count = 0
        return class_a

登入後複製

重要的部分是如何使用 patch.object 函數,該函數來自 Python 中的 unittest.mock 模組。它在測試中用於臨時用模擬或其他值替換給定物件的屬性。

參數

  1. target=ClassA:我們要修補其屬性的物件(通常是類別)。
  2. attribute="__init__": 我們要修補的屬性的名稱。
  3. return_value=None:用不執行任何操作的函數取代 __init__ 方法

透過這種方式,我們可以在我們的裝置中建立模擬變數。
閱讀有關 patch.object

的更多信息

測驗技巧

我寫這個教學是為了這種情況,無論出於何種原因,我們都無法更改A類的程式碼。但是,我通常建議如果可能的話修改程式碼,不是為了改變邏輯,而是為了使其更易於測試.

以下是如何修改 A 類以使其更易於測試的一些範例:

選項 1: 將 B 類和 C 類的實例作為參數傳遞。
這樣,當我們編寫固定裝置時,我們可以傳遞模擬而不是實例。

class ClassA:
    def __init__(self, class_b_instance, class_c_instance):
        self.class_b = class_b_instance
        self.class_c = class_c_instance
        self.count = 0
登入後複製

選項 2: 建立一個指示測試模式的布林變數。
這樣我們就可以決定 A 類別的哪些欄位在啟動時會或不會取得值。

class ClassA:
    def __init__(self, test_mode=False):
        if not test_mode:
            self.class_b = ClassB()
            self.class_c = ClassC()
        self.count = 0
登入後複製

選項 3: 在單獨的方法中進行類別啟動。
這種方法使我們可以選擇避免在測試模組中呼叫 set_class_variables。

class ClassA:
    def __init__(self):
        self.class_b = None
        self.class_c = None
        self.count = None

    def set_class_variables(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0
登入後複製

希望這有幫助! :)

以上是模擬 Python 類別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!