我有一个“MyClass”类,代码如下所示。
class MyClass:
def __init__(update_type_id='1')
self.update_type_id = update_type_id
self._cursor = <database_connection).cursor()
def update_start_dt(self):
self._update_job_ctrl_start_dt()
def _update_job_ctrl_start_dt(self):
update_sql, v_1 = self._get_update_sql(self._update_type_id)
logger.debug(f'Update sql: {update_sql} and v_1: {v_1}')
def _get_update_sql(self, update_type_id: int) -> Tuple:
sql = f"SELECT start_sql, end_sql FROM <database.table> where update_type_key = {self._update_type_id}"
self._run_sql(sql)
record = self._cursor.fetchone()
if record:
return record
else:
logger.error(f'Record Not Found. Update type key ({update_type_id}) not found in the table in the database')
raise Exception
def _run_sql(self, sql_statement: str):
try:
self._cursor.execute(sql_statement)
except (Exception, Error) as e:
logger.error(f'Error {e} encountered when reading from table')
raise e我正在尝试使用pytest-mock编写一个测试函数,这将测试update_start_dt方法。该方法在内部调用一系列私有方法,我很难模拟贯穿所有私有方法的代码。有人能帮我弄明白我们能用什么方式嘲笑吗?
我试图参考多个在线网站,但无法得到一个完整的图片。
class TestMyClass:
def test_update_start_dt(mocker,mock_get_connection,mock_run_sql):
mock_manager = mocker.Mock()
mock_get_update_sql = mock_manager.patch('MyClass._get_update_sql')
mock_get_update_sql.return_value = ('123','234')
myclass = MyClass(update_type_id='1')
myclass.update_start_dt()以上测试代码的错误如下所示
update_sql, v_1 = self._get_update_sql(self._update_type_id)
ValueError: not enough values to unpack (expected 2, got 0)发布于 2022-06-18 12:37:55
这里的问题是,您正在对正在创建的Mock对象进行修补,为了测试的目的,您不需要显式地创建Mock对象。下面展示了如何测试它,我们直接在类上进行patch测试。
class MyClass:
def __init__(self, update_type_id='1'):
self._update_type_id = update_type_id
self._cursor = None
def update_start_dt(self):
self._update_job_ctrl_start_dt()
def _update_job_ctrl_start_dt(self):
update_sql, v_1 = self._get_update_sql(self._update_type_id)
logger.debug(f'Update sql: {update_sql} and v_1: {v_1}')
def _get_update_sql(self, update_type_id: int):
sql = f"SELECT start_sql, end_sql FROM <database.table> where update_type_key = {self._update_type_id}"
self._run_sql(sql)
record = self._cursor.fetchone()
if record:
return record
else:
logger.error(f'Record Not Found. Update type key ({update_type_id}) not found in the table in the database')
raise Exception
def _run_sql(self, sql_statement: str):
try:
self._cursor.execute(sql_statement)
except (Exception, Error) as e:
logger.error(f'Error {e} encountered when reading from table')
raise e
def test_update_start_dt(mocker):
mock_get_update_sql = mocker.patch.object(MyClass, "_get_update_sql")
mock_get_update_sql.return_value = ("123", "234")
myclass = MyClass(update_type_id='1')
myclass.update_start_dt()=========================================== test session starts ============================================
platform darwin -- Python 3.8.9, pytest-7.0.1, pluggy-1.0.0
rootdir: ***
plugins: mock-3.7.0
collected 1 item
test_script.py . [100%]
======================================= 1 passed, 1 warning in 0.01s =======================================如果调用创建的Mock对象而不是类,代码就会工作。如下所示。
def test_update_start_dt(mocker):
mock_manager = mocker.Mock()
mock_get_update_sql = mock_manager.patch('MyClass._get_update_sql')
mock_get_update_sql.return_value = ('123','234')
# Notice how we use `mock_manager` instead of MyClass
# tests will now pass
myclass = mock_manager(update_type_id='1')
myclass.update_start_dt()希望你能看到现在的问题。
https://stackoverflow.com/questions/72662060
复制相似问题