首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pytest-mock模拟对象和对象方法

使用pytest-mock模拟对象和对象方法
EN

Stack Overflow用户
提问于 2021-05-21 03:58:47
回答 1查看 3.3K关注 0票数 0

我正在尝试使用pytest-mock进行模拟。这个库本质上是mockpatch的插件/包装器。

我的问题被定义为:

我有一个使用SQL Alchemy的应用程序(mymodule.py)。基本上,有一个函数定义了SQL Alchemy中的一些对象,并返回包含这些对象的字典。

代码语言:javascript
复制
def some_function1():
    # some code
    from sqlalchemy import create_engine, MetaData, Table

    engine = create_engine(f"mysql+pymysql://{username}:{password}@{host}:{port})
    meta = MetaData(engine)
    my_table = Table(
        'my_table',
        meta,
        autoload=True,
        schema="some_schema"
    )
    db_tools = {"engine": engine, "table": my_table}
    return db_tools

然后,第二个函数将该输出字典作为输入并使用它们:

代码语言:javascript
复制
def some_function2(db_tools, data):

    sql_query = db_tools["table"].insert().values(data)
    db_tools["engine"].execute(sql_query)
    # some more code

所以现在我在写单元测试,我不想和真正的数据库通信。所以我只需要模拟所有与sqlalchemy相关的东西。到目前为止,我已经通过执行以下操作成功模拟了create_engineMetaDataTable

代码语言:javascript
复制
mocker.patch(
    'my_module.create_engine',
    return_value=True
)
mocker.patch(
   'my_module.MetaData',
   return_value=True
)
mocker.patch(
   'my_module.Table',
   return_value=True
)

这让我可以测试some_function1。但现在我需要测试some_function2,它使用.insert().values.execute()方法或属性。我怎么才能修补它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-22 02:19:03

模拟some_function1没有太多好处,因为它只会建立到数据库的连接。它不需要任何输入,它返回的只是一个指向表和连接的字典。关于some_function2,我们可以在db_tools参数中传入多个MagicMock并使用configure_mock

代码语言:javascript
复制
def test_some_function2(mocker):
    mock_table = mocker.MagicMock()
    mock_engine = mocker.MagicMock()

    fake_query = "INSERT blah INTO foo;"
    fake_data = [2, 3]

    mock_table.configure_mock(
        **{
            "insert.return_value": mock_table,
            "values.return_value": fake_query
        }
    )

    db_tools = {
        "table": mock_table,
        "engine": mock_engine
    }

    some_function2(db_tools, fake_data)

    mock_table.insert.assert_called_once()
    mock_table.values.assert_called_once_with(fake_data)

    mock_engine.execute.assert_called_once_with(fake_query)

当测试运行时,它返回以下内容。

代码语言:javascript
复制
========================================================== test session starts ==========================================================
platform darwin -- Python 3.7.4, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: ***
plugins: mock-3.2.0
collected 1 item                                                                                                                        

test_foo.py .                                                                                                                     [100%]

=========================================================== 1 passed in 0.01s ===========================================================
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67627176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档