Python中mock.patch用法 單元測試mock模塊patch方法模擬對象解析

mock.patch 是 python 單元測試中用于臨時替換對象工具。它屬于 unittest.mock 模塊,可作為裝飾器或上下文管理器使用,能在測試期間將指定對象替換成 mock 實例,并在測試結束后自動恢復原狀。常見用法包括:1. 替換函數返回值,例如模擬 requests.get() 的響應;2. 使用裝飾器或 with 語句控制 patch 的作用范圍;3. 區別 patch 類方法與實例方法;4. 注意路徑準確性、作用域及副作用處理,如使用 side_effect 模擬異常或動態返回結果。

在寫python單元測試的時候,mock.patch 是一個非常實用的工具。它能讓我們在測試過程中臨時替換掉某些對象,比如函數、類或者模塊,這樣我們就能控制它們的行為,而不依賴真實環境。


什么是 mock.patch?

mock.patch() 是 Python unittest.mock 模塊中的一個裝飾器或上下文管理器,用于在測試期間“打補丁”某個對象。也就是說,它可以在運行時替換成你指定的對象,比如一個 Mock 實例,等測試結束后自動恢復原樣。

常見用法包括:

  • 替換某個模塊中的函數
  • 模擬某個類的返回值
  • 控制外部依賴(如網絡請求、數據庫讀取)

怎么用 mock.patch?

替換函數返回值

這是最常見的使用方式之一。比如你想測試某個調用了 requests.get() 的函數,但不想讓它真正發起網絡請求。

立即學習Python免費學習筆記(深入)”;

from unittest.mock import patch import requests  def fetch_data():     response = requests.get('https://example.com')     return response.status_code  @patch('requests.get') def test_fetch_data(mock_get):     mock_get.return_value.status_code = 200     assert fetch_data() == 200

這里的關鍵是:你要 patch 的名字必須是你被測試代碼中實際導入和使用的那個名字,而不是原始定義的位置。

使用裝飾器還是上下文管理器?

  • 裝飾器適用于整個測試函數都要替換的情況。
  • with 語句適合只在某一段代碼里替換。
# 裝飾器寫法 @patch('module.ClassName') def test_something(mock_class):     ...  # 上下文寫法 def test_something():     with patch('module.ClassName') as mock_class:         ...

兩種方式效果一樣,選哪個看具體場景。

patch 類和實例方法的區別

有時候你會想模擬某個類的方法行為,這時候需要注意 patch 的目標不同:

  • patch 類方法:直接 patch 類上的方法
  • patch 實例方法:需要先構造實例,再 patch 實例上的方法

例如:

class MyClass:     def method(self):         return 'real'  # Patch 整個類的方法 @patch.object(MyClass, 'method', return_value='mocked') def test_class_method(mock_method):     obj = MyClass()     assert obj.method() == 'mocked'

常見問題與注意事項

  • 路徑要寫對:patch 的路徑一定要準確,通常是模塊+對象名,比如 ‘my_module.requests.get’
  • 作用域別搞混:如果你在 A 模塊里導入了 B 模塊的函數,那要 patch 的是 A 模塊里看到的那個引用
  • 注意副作用:如果被 mock 的函數有多個調用點,return_value 可能不夠用,可以用 side_effect 來模擬異常或動態返回

side_effect 示例:

mock_get.side_effect = Exception('Network error')

基本上就這些。mock.patch 不復雜,但在實際項目中很容易因為路徑寫錯或理解偏差導致 mock 失敗,所以多注意細節。

? 版權聲明
THE END
喜歡就支持一下吧
點贊10 分享