有没有一种方法可以使用mock在pytest中模拟完整的代码



例如,每次测试发现

database.db.session.using_bind("reader")

我想删除using_bind("reader")),只使用

database.db.session

使用模拟

尝试在conftest.py中这样使用它

@pytest.fixture(scope='function')
def session(mocker):
mocker.patch('store.database.db.session.using_bind', return_value=_db.db.session)

但到目前为止,一切都没有奏效。

测试代码:

from store import database     
results = database.db.session.using_bind("reader").query(database.Order.id).join(database.Shop).filter(database.Shop.deleted == False).all(), 

我得到

AttributeError: 'scoped_session' object has no attribute 'using_bind' as an error.

让我们从一个MRE开始,其中被测试的代码使用了一个伪数据库:

from unittest.mock import Mock, patch
class Session:
def using_bind(self, bind):
raise NotImplementedError(f"Can't bind {bind}")
def query(self):
return "success!"

database = Mock()
database.db.session = Session()

def code_under_test():
return database.db.session.using_bind("reader").query()

def test():
assert code_under_test() == "success!"

运行此测试失败:

E       NotImplementedError: Can't bind reader

因此,我们想在code_under_test中模拟session.using_bind,使其返回session——这将使我们的测试通过

我们使用patch来做到这一点,就像这样:

@patch("test.database.db.session.using_bind")
def test(mock_bind):
mock_bind.return_value = database.db.session
assert code_under_test() == "success!"

请注意,我的代码在一个名为test.py的文件中,所以我的patch调用适用于test模块——您需要调整它,以指向您自己代码中正在测试的模块。

还要注意,在调用测试中的代码之前,我需要设置mock

最新更新