标签: pytest-mock

unittest.mock、mock、mocker 和 pytest-mock 之间有什么区别?

我是 Python 开发新手,我正在使用pytest编写测试用例,我需要模拟一些行为。谷歌搜索pytest 的最佳模拟库,只会让我感到困惑。我见过unittest.mock、mock、mocker 和pytest-mock。不太确定该使用哪一个。有人可以解释一下它们之间的区别并向我推荐一个吗?

python tdd pytest python-unittest pytest-mock

24
推荐指数
1
解决办法
1万
查看次数

如何使用 pytest-mock 指定模拟函数的返回值?

下面打印False。这不是嘲笑的方式吗?

我尝试更改该函数的路径,但它出错了,因此路径似乎是正确的。我缺少什么?

import pytest

from deals.services.services import is_user_valid


class TestApi:
    def test_api(self, mocker):
        mocker.patch('deals.services.services.is_user_valid', return_value=True)
        print(is_user_valid("sdfds", "sdfsdf"))
Run Code Online (Sandbox Code Playgroud)

python pytest python-3.x pytest-mock

15
推荐指数
1
解决办法
3万
查看次数

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

我正在尝试用于pytest-mock嘲笑。mock该库本质上是和的插件/包装器patch

我的问题定义为:

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

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
Run Code Online (Sandbox Code Playgroud)

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

def some_function2(db_tools, data):

    sql_query = db_tools["table"].insert().values(data)
    db_tools["engine"].execute(sql_query)
    # some more code
Run Code Online (Sandbox Code Playgroud)

所以现在我正在编写单元测试,并且我不想实际与真实的数据库进行通信。所以我只需要嘲笑所有sqlalchemy相关的东西。到目前为止,我已经成功模拟create_engine,MetaDataTable通过执行以下操作:

mocker.patch(
    'my_module.create_engine',
    return_value=True
)
mocker.patch(
   'my_module.MetaData',
   return_value=True …
Run Code Online (Sandbox Code Playgroud)

python unit-testing pytest pytest-mock

10
推荐指数
1
解决办法
3万
查看次数

使用模拟获取应用的函数输入数据框

我有以下功能

def main():
    (
        pd.DataFrame({'a': [1, 2, float('NaN')], 'b': [1.0, 2, 3]})
        .dropna(subset=['a'])
        .assign(
            b=lambda x: x['b'] * 2
        )
        .apply(do_something_with_each_row, axis='columns')
    )

def do_something_with_each_row(one_row):
    # do_something_with_row
    print(one_row)
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我想查看在所有链接操作之后构建的数据框,并在调用do_something_with_each_row. 最后一个函数不返回数据帧(它只是迭代所有行,类似于iterrow)。

我试图apply像这样模拟这个函数:

# need pytest-mock and pytest
import pandas as pd


def test_not_working(mocker):
    mocked_apply = mocker.patch.object(pd.Dataframe, 'apply')
    main()
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我无法访问输入到的数据帧apply以测试其内容。

我还试图嘲笑do_something_with_each_row

# need pytest-mock and pytest
import pandas as pd


def test_not_working_again(mocker):
    mocked_to_something = mocker.patch('path.to.file.do_something_with_each_row')
    main()
Run Code Online (Sandbox Code Playgroud)

但这次我有所有带有行参数的调用,但它们都有None值。

我如何获取apply调用函数的数据帧并检查它是否确实与以下内容相同: …

pytest python-3.x pandas pytest-mock

8
推荐指数
1
解决办法
325
查看次数

How to mock raise urllib errors

After reading this in the python docs, I am catching the HTTPError and URLError exceptions in get_response_from_external_api that the make_request_and_get_response (via urllib's urlopen call) can raise:

foo.main.py

from urllib.request import urlopen
import contextlib
from urllib.error import HTTPError, URLError

def make_request_and_get_response(q):
    with contextlib.closing(urlopen(q)) as response:
        return response.read()

def get_response_from_external_api(q):
    try:
        resp = make_request_and_get_response(q)
        return resp
    except URLError as e:
        print('Got a URLError: ', e)
    except HTTPError as e:
        print('Got a HTTPError: ', e)

if __name__ == "__main__":
    query = …
Run Code Online (Sandbox Code Playgroud)

mocking urllib pytest python-3.x pytest-mock

6
推荐指数
1
解决办法
162
查看次数

Python pytest-mock assert_has_calls

我正在研究名为 pytest-mock (https://github.com/pytest-dev/pytest-mock)的优秀 pytest 插件,现在我正在尝试使用assert_has_calls 的一些示例。简而言之,我正在测试 B 类的实例,更具体地说,该实例如何与 A 类的实例交互(我在其中模拟了“time_consuming_task”方法)。

该示例正在使用 alt。B(参见代码中的注释)。我更喜欢替代方案。A,而是直接模拟 A 类中的方法,而不是模拟通过类 B 的实例(obj)访问的类 A 的实例中的方法。

class A(object):
    def do_time_consuming_task(self, timeout):
        return True


class B(object):
    def __init__(self):
        self.a = A()

    def do_work(self, timeout):
        return self.a.do_time_consuming_task(timeout)


def test_calls(mocker):
    # Prepare
    obj = B()
    #mock_a = mocker.patch.object(A, 'do_time_consuming_task', autospec=True)  # Alt. A
    mock_a = mocker.patch.object(obj.a, 'do_time_consuming_task', autospec=True)  # Alt. B
    mock_a.return_value = True

    # Exercise
    obj.do_work(timeout=100)
    obj.do_work(timeout=50)

    # Assert
    mock_a.assert_has_calls([mocker.call(100), mocker.call(50)])
Run Code Online (Sandbox Code Playgroud)

python python-unittest python-unittest.mock pytest-mock

6
推荐指数
1
解决办法
8836
查看次数

Pytest lambda 处理程序传递事件和上下文

我正在使用 pytest 为我的 lambda 函数编写单元测试。我不知道应该如何将事件参数传递给函数调用。我了解到可以使用@pytest.fixture 来实现。我对 Python 和 pytest 非常陌生。相信我以错误的方式使用固定装置。请帮我!!

下面是我的 lambda 处理程序:

lambda_service.py

def lambda_handler(event, context):   
    logger.info('Event received: ' + json.dumps(event))
    try:
        sort = (event['sort'])
        size = int(event['size'])
        page = int(event['page'])

        list_response = MyService().get_people_list(sort, size, page)
        logger.info(list_response)

    except Exception as e:
        logger.error("Unable to fetch details")
        logger.exception(e)

    return list_response
Run Code Online (Sandbox Code Playgroud)

这是我的测试课-

class TestServiceHandler:
    @pytest.fixture
    def event(self):
        return {
            "sort": "asc",
            "size": 5,
            "page": 0
        }
    @pytest.fixture
    def context(self):
        return None

    def test_lambda_handler(self):
        result = lambda_service.lambda_handler(self.event, self.context)
        assert_valid_schema(result, 'vendor_list.json')
Run Code Online (Sandbox Code Playgroud)

运行此测试时出现以下错误

line 17, …
Run Code Online (Sandbox Code Playgroud)

python fixtures pytest pytest-mock

6
推荐指数
1
解决办法
6295
查看次数

如何在pytest中使用monkeypatch或mock删除库?

如果我的库中有一个contrib附加程序,其中包含依赖项(例如requests),我希望用户必须安装该附加程序才能访问 CLI API,但我在 CI 测试期间安装了 contrib 附加程序,我如何使用pytestMonkeyPatch删除测试期间的依赖关系以确保我的检测正确?

例如,如果contrib额外的内容会另外安装requests,那么我希望用户必须这样做

$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)

然后能够在命令行上使用 CLI API,如下所示

$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)

wheremyfunction使用requests依赖项

$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)

我如何在测试中模拟或猴子补丁 ,以便我可以确保用户正确地收到警告以及如果他们这样做requestspytestModuleNotFoundError

$ python -m pip install mylib
$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)

?在阅读了有关 pytest 标签的其他一些问题后,我仍然认为我不明白如何做到这一点,所以我在这里问。

python monkeypatching pytest pytest-mock

6
推荐指数
1
解决办法
1484
查看次数

pytest-mock 的会话范围

我正在寻找如何使用 pytest-mock 插件的会话范围的“session-mocker”装置的示例。

如何修改文档提供的示例以在特定测试中使用它是相当清楚的:

def test_foo(session_mocker):
    session_mocker.patch('os.remove')
    etc...
Run Code Online (Sandbox Code Playgroud)

但我对这个全局装置应该在哪里以及如何初始化感到困惑。例如,假设我想为所有测试模拟“os.remove”。我是否在 confftest.py 中进行了设置?如果是,我该怎么做?

python pytest pytest-mock

6
推荐指数
1
解决办法
5564
查看次数

如何在 Python 中模拟类实例(而不是类函数)

我很难模拟一个对象的实例。

我想编写一个单元测试来测试使用类实例的“my_func”函数。我知道如何模拟类函数,但是,我不知道如何模拟类(对象)本身(而不是函数)的实例。

在我的模块文件中:

# my_module.py

import fancypackage1
import fancypackage2
def my_func():
    x = fancypackage1.SomeClass.somefunction() # I know how to mock this
    myclient = fancypackage2.Client() # I don't know how to mock this
    myresult = do_something(myclient, x) # I know how to mock this
    return myresult
Run Code Online (Sandbox Code Playgroud)

在我的测试文件中:

# test_my_module.py

import pytest
import mock
import fancypackage1
import fancypackage2
from my_module import my_func    

def test_my_func(mocker):
    mock_someclass_somefunction = mocker.patch('my_module.fancypackage1.SomeClass.somefunction')
    mock_someclass_somefunction.return_value = 'hello'

    mock_client = mocker.patch.object(fancypackage2.Client, '__init__') # TypeError: __init__() should return None, not 'MagicMock' …
Run Code Online (Sandbox Code Playgroud)

mocking pytest python-3.x pytest-mock

6
推荐指数
1
解决办法
5536
查看次数