Python 3.x 如何模拟构造函数pytest
这些类的定义如下-Python 3.x 如何模拟构造函数pytest,python-3.x,object,constructor,mocking,pytest,Python 3.x,Object,Constructor,Mocking,Pytest,这些类的定义如下- class User: def __init__(self): self.__client = ManagerClient() self.__data = None def get_data(self): if self.__data is None: self.__get_password() return self.__data de
class User:
def __init__(self):
self.__client = ManagerClient()
self.__data = None
def get_data(self):
if self.__data is None:
self.__get_password()
return self.__data
def __get_password(self):
self.__password = self.__client.fetch_secret()
class ManagerClient:
def fetch_secret():
pass
我想对get_data()进行单元测试,因为User类的构造函数正在初始化manager客户端的对象,并且该对象稍后将用于调用fetch_secret(),我应该如何模拟?在技术上,当为单元测试测试测试
get_data
方法时,我们不关心\u get_password
或其实现。我们只想测试get\u data
的各种逻辑分支。按照这一思路,我们将简单地模拟\uuu获取密码
及其操作。如果我们想测试\uuu获取\u密码
,我们将为此使用单独的测试
另一件需要注意的事情是,您对属性和方法使用了双下划线,它们在文本中被替换为\u classname\u attribute
。这就是为什么我们使用如下所示的措辞进行修补和模拟。你可以了解更多
另外,您的get_data
功能基本上不健全。根据其逻辑,它有两种不同的返回类型,它可以返回某些内容,也可以在对象上设置一个属性,这被认为是错误的做法
鉴于以下项目结构:
stackoverflow/
├── mypackage
│ ├── __init__.py
│ └── users.py
└── tests
├── __init__.py
└── test_users.py
我们将编写的测试如下所示
from unittest.mock import MagicMock, patch
from mypackage.users import User
@patch("mypackage.users.ManagerClient")
def test_get_data_valid(mock_client):
expected = "fizz"
klass = User()
klass._User__data = expected
actual = klass.get_data()
assert actual == expected
@patch("mypackage.users.ManagerClient")
@patch.object(User, "_User__get_password")
def test_get_data_none(mock_pwd, mock_client):
klass = User()
klass.get_data()
mock_pwd.assert_called_once()
@patch("mypackage.users.ManagerClient")
def test_get_password(mock_client):
mock_client.configure_mock(
**{
"fetch_secret.return_value": "buzz",
"return_value": mock_client
}
)
klass = User()
klass._User__get_password()
assert klass._User__password == "buzz"
======================================= test session starts ========================================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: ***/stackoverflow
collected 3 items
tests/test_users.py ... [100%]
======================================== 3 passed in 0.06s =========================================
根据要求,我们在每个测试中模拟
ManagerClient
,这样它就不会被初始化。这是通过相关的类和方法实现的。我们还通过为fetch\u secret
设置可测试的返回值来测试\u get\u password
方法。我们在最终测试中使mock_客户机
返回自身的原因是,当您初始化mock
对象时,它返回一个新的对象。为了简单起见,我们只需将Mock
的返回值设置为自身,这样我们就不必创建新的对象。我不想初始化ManagerClient的对象,这里的这行“klass=User()”将执行init()并初始化ManagerClient。如果我想测试u get_password呢?我应该如何模拟自己。_client.fetch_secret()?根据注释更新答案,并将此标记为已解决如果这回答了您的问题请帮助:我还想为_get_password编写单元测试?我应该如何模仿自己。u client.fetch_secret()?