![](/img/trans.png)
[英]Using mock.patch.object to wrap a method on all objects of a class
[英]Mock/Patch specific object method inside a class method
我知道標題很混亂,但為了清楚起見,我創建了一個我必須轉置的樣本:
假設我在class_file.py
中有這段代碼
class CarDealership:
def allow_car_out_of_the_dealership(self, car):
logger.info(f"Driving out of the dealership")
drivers_license = car.driver.wallet.get_drivers_license()
if drivers_license:
try:
allow_car_removal(car, drivers_license)
except:
deny_car_removal(car, drivers_license)
我正在嘗試測試調用deny_car_removal
方法的情況。 get_valid_license()
是特定於driver.wallet
的方法,不會以任何方式、形狀或形式在class_file.py
中導入或引用。
問題是,如果get_valid_license
在實際情況下沒有返回任何有效的東西,那么代碼會采用完全不同的方式。 我正在嘗試修補drivers_license
,以便最終將其帶到我需要的地步。
我猜test_class_file.py
應該是這樣的:
class CarDealershipTests(BaseTestCase):
@patch('class_file.CarDealership.deny_car_removal')
def test_deny_car_removal(self):
# something here
self.assertTrue(mock_deny_car_removal.called)
我通過查看其他 StackOverflow 答案嘗試了一些事情,但沒有奏效:
car
中模擬一個完整的driver
實例,如下所示: def setUp(self) -> None:
self._create_car
def _create_car(self):
car = Car()
car.driver = MagicMock()
@patch.object(class_file.CarDealership.allow_car_out_of_the_dealership, "car.driver.wallet.get_valid_license")
@patch.object(class_file.CarDealership.allow_car_out_of_the_dealership, "drivers_license")
@patch("class_file.CarDealership.allow_car_out_of_the_dealership.car.driver.wallet.get_valid_license")
@patch("class_file.CarDealership.allow_car_out_of_the_dealership.drivers_license")
假設您有一個文件,其內容如下所示:
import logging
logger = logging.getLogger(__name__)
class CarRemovalFailure(BaseException):
pass
class CarDealership:
def allow_car_out_of_the_dealership(self, car):
logger.info("Driving out of the dealership")
drivers_license = car.driver.wallet.get_drivers_license()
if drivers_license:
try:
allow_car_removal(car, drivers_license)
except CarRemovalFailure:
deny_car_removal(car, drivers_license)
為了調用deny_car_removal
,我們需要allow_car_removal
拋出一個Exception
。 這可以通過使用Mock
object 的side_effect
屬性輕松完成。
我沒有在這個測試中加入任何設置/拆卸,而是說明side_effect
是如何工作的,以及它是如何最終調用deny_car_removal
的。
from unittest.mock import MagicMock, patch
from class_file import CarDealership, CarRemovalFailure
@patch("class_file.allow_car_removal")
@patch("class_file.deny_car_removal")
def test_deny_car(mock_deny, mock_allow):
mock_allow.side_effect = CarRemovalFailure("Failed!")
car = MagicMock()
cd = CarDealership()
cd.allow_car_out_of_the_dealership(car)
car.driver.wallet.get_drivers_license.assert_called_once()
mock_deny.assert_called_once()
運行時輸出以下內容:
============================= test session starts ==============================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: ****
collected 1 item
tests/test_car.py . [100%]
============================== 1 passed in 0.05s ===============================
在您的示例中,您可能不想在嘗試測試邏輯時修補deny_car_removal
,但由於我不知道那可能是什么,所以我最終修補了它。 這樣做的目的是為了說明實際上 function 確實被調用了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.