我是 Python 开发新手,我正在使用pytest编写测试用例,我需要模拟一些行为。谷歌搜索pytest 的最佳模拟库,只会让我感到困惑。我见过unittest.mock、mock、mocker 和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) 我正在尝试用于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,MetaData并Table通过执行以下操作:
mocker.patch(
'my_module.create_engine',
return_value=True
)
mocker.patch(
'my_module.MetaData',
return_value=True …Run Code Online (Sandbox Code Playgroud) 我有以下功能
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调用函数的数据帧并检查它是否确实与以下内容相同: …
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) 我正在研究名为 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) 我正在使用 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) 如果我的库中有一个contrib附加程序,其中包含依赖项(例如requests),我希望用户必须安装该附加程序才能访问 CLI API,但我在 CI 测试期间安装了 contrib 附加程序,我如何使用pytest来MonkeyPatch删除测试期间的依赖关系以确保我的检测正确?
例如,如果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 标签的其他一些问题后,我仍然认为我不明白如何做到这一点,所以我在这里问。
我正在寻找如何使用 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 中进行了设置?如果是,我该怎么做?
我很难模拟一个对象的实例。
我想编写一个单元测试来测试使用类实例的“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) pytest-mock ×10
pytest ×9
python ×7
python-3.x ×4
mocking ×2
fixtures ×1
pandas ×1
tdd ×1
unit-testing ×1
urllib ×1