Pytest-模拟链式调用
Pytest- mock chained call
我正在尝试在 pytest
(和 pytest-mock
包)中模拟链式调用,但由于某些未知的(对我来说)原因它不起作用,这意味着我没有得到从我的模拟中嘲笑 return_value
。看起来它创建了 MagicMock
的对象,但没有定义 return_value
。我的猜测是它与链式调用有关。
class DatabaseService():
def __init__(self):
self.db = next(get_db())
self.categories = {}
def save(self, product_id):
if not self.categories:
self._load_existing_categories()
...
[rest of the code]
def _load_existing_categories(self):
# result = self.db.execute(select(Category).order_by(Category.id)).all() <-- This is my original line, but I can't make it working even with simplified version (line below)
result = self.db.execute().all()
for obj in result:
print("Result")
print(obj)
self.categories[obj.Category.name] = obj.Category
这是我的测试:
def test_load_from_database(mocker):
session = mocker.patch('src.mysql.get_db')
session.execute.all.return_value = ['1st element', '2nd element']
# I tried also mock it by these ways:
# session = mocker.MagicMock()
# session.session.execute().all().return_value = ['1st element', '2nd element']
# session.get_db.execute().all().return_value = ['1st element', '2nd element']
# session.execute.all = ['1st element', '2nd element']
service = DatabaseService()
service.save = mocker.MagicMock(side_effect=service.save)
service.db = session
service.save(123)
[here will be some assert once I make it working]
出于某种原因,mock of self.db.execute().all()
没有 return 任何东西。循环内的代码甚至一次都没有执行。
当我打印 print(result)
时,我得到:
<MagicMock name='get_db.execute().all()' id='140427147903424'>
但看起来 return_value
没有分配给它,所以要么它不是同一个对象,要么值以某种方式被删除。
你的代码调用这个:
self.db.execute().all()
在您的测试中,您将设置为:
session.execute.all.return_value
我认为你应该设置:
session.execute.return_value.all.return_value
因为您的代码 调用 执行,所以您需要在其 return 值上设置模拟。
我正在尝试在 pytest
(和 pytest-mock
包)中模拟链式调用,但由于某些未知的(对我来说)原因它不起作用,这意味着我没有得到从我的模拟中嘲笑 return_value
。看起来它创建了 MagicMock
的对象,但没有定义 return_value
。我的猜测是它与链式调用有关。
class DatabaseService():
def __init__(self):
self.db = next(get_db())
self.categories = {}
def save(self, product_id):
if not self.categories:
self._load_existing_categories()
...
[rest of the code]
def _load_existing_categories(self):
# result = self.db.execute(select(Category).order_by(Category.id)).all() <-- This is my original line, but I can't make it working even with simplified version (line below)
result = self.db.execute().all()
for obj in result:
print("Result")
print(obj)
self.categories[obj.Category.name] = obj.Category
这是我的测试:
def test_load_from_database(mocker):
session = mocker.patch('src.mysql.get_db')
session.execute.all.return_value = ['1st element', '2nd element']
# I tried also mock it by these ways:
# session = mocker.MagicMock()
# session.session.execute().all().return_value = ['1st element', '2nd element']
# session.get_db.execute().all().return_value = ['1st element', '2nd element']
# session.execute.all = ['1st element', '2nd element']
service = DatabaseService()
service.save = mocker.MagicMock(side_effect=service.save)
service.db = session
service.save(123)
[here will be some assert once I make it working]
出于某种原因,mock of self.db.execute().all()
没有 return 任何东西。循环内的代码甚至一次都没有执行。
当我打印 print(result)
时,我得到:
<MagicMock name='get_db.execute().all()' id='140427147903424'>
但看起来 return_value
没有分配给它,所以要么它不是同一个对象,要么值以某种方式被删除。
你的代码调用这个:
self.db.execute().all()
在您的测试中,您将设置为:
session.execute.all.return_value
我认为你应该设置:
session.execute.return_value.all.return_value
因为您的代码 调用 执行,所以您需要在其 return 值上设置模拟。