我正在尝试了解这些mock/monkeypatch/pytest-mock功能。
让我知道是否可行。如果不能,请建议我如何测试此代码。
我的代码结构:
/
./app
../__init__.py
../some_module1
.../__init__.py
../some_module2
.../__init__.py
./tests
../test_db.py
Run Code Online (Sandbox Code Playgroud)
在/app/__init__.py此处启动我的应用程序(如果有帮助,则为Flask应用程序),并初始化与MongoDB数据库的数据库连接对象:
# ...
def create_app():
# ...
return app
db_conn = DB()
Run Code Online (Sandbox Code Playgroud)
在some_module1与some_module导入db_conn对象,并把它作为自己的部分功能:
## some_module1/__init__.py
from app import db_conn
...
db = db_conn.db_name2.db_collection2
def some_func1():
data = db.find()
# check and do something with data
return boolean_result
...
## some_module2/__init__.py
from app import db_conn
...
db = db_conn.db_name1.db_collection1
def some_func2():
data = db.find()
# check and do something …Run Code Online (Sandbox Code Playgroud) 我们最近从单元测试切换到了 pytest。mocker.patch我在使用上下文管理器时遇到了一个奇怪的问题。考虑以下示例。
模块_a.py
class MyClass:
def value(self):
return 10
Run Code Online (Sandbox Code Playgroud)
模块_b.py
import module_a
class AnotherClass:
def get_value(self):
return module_a.MyClass().value()
Run Code Online (Sandbox Code Playgroud)
测试模块b.py
from module_b import AnotherClass
def test_main_2(mocker):
with mocker.patch('module_a.MyClass.value', return_value=20):
value = AnotherClass().get_value()
assert value == 20
value = AnotherClass().get_value()
assert value == 10
Run Code Online (Sandbox Code Playgroud)
我希望一旦上下文管理器退出,MyClass 的 value method 方法将被恢复(返回值 10),但是测试在第二个断言语句上失败并出现断言错误20 != 10如果我使用完全相同的测试,但替换mocker.patch为unittest.mock.patch,它通过。我认为 pytest-mock 与 unittest.mock 共享相同的 API,所以我很困惑为什么会有差异。
我正在尝试模拟对 boto3 的一些调用,看起来被模拟的函数正在返回正确的值,并且看起来如果我更改断言使其不再匹配断言中传递的内容失败,因为输入参数不匹配,但是如果我让它们匹配,那么断言失败:
E AssertionError: assert None
E + where None = <bound method wrap_assert_called_with of <MagicMock name='get_item' id='139668501580240'>>(TableName='TEST_TABLE', Key={'ServiceName': {'S': 'Site'}})
E + where <bound method wrap_assert_called_with of <MagicMock name='get_item' id='139668501580240'>> = <MagicMock name='get_item' id='139668501580240'>.assert_called_with
E + where <MagicMock name='get_item' id='139668501580240'> = <botocore.client.DynamoDB object at 0x7f071b8251f0>.get_item
E + where <botocore.client.DynamoDB object at 0x7f071b8251f0> = site_dao.ddb_client
Run Code Online (Sandbox Code Playgroud)
dynamo DB 对象是一个全局变量。
ddb_client = boto3.client("dynamodb")
def query_ddb():
"""Query dynamo DB for the current strategy.
Returns:
strategy (str): The latest strategy from dynamo DB. …Run Code Online (Sandbox Code Playgroud) 在下面显示的代码片段中,我想测试函数中的函数调用顺序run(),即,在调用之后f_3调用:f_2f_1
class TestMock:
def f_1(self) -> None:
pass
def f_2(self) -> None:
pass
def f_3(self) -> None:
pass
def run(self) -> None:
self.f_1()
self.f_2()
self.f_3()
Run Code Online (Sandbox Code Playgroud)
有什么方法可以使用 来做到这一点吗pytest-mock?我尝试在测试文件中模拟f_1、f_2和函数并使用with ,但是没有成功。f_3assert_has_callsany_order=False
预先感谢您的任何帮助或提示!
最好的,阿列克谢
我发现requests_mock用作固定装置pytest适用于所有请求,即使它们没有设置。
我不确定这是一个requests_mock/pytest错误还是我遗漏了一些东西。最终,我不需要模拟“api-b”调用,但我不知道如何避免它。
def test_reqs(requests_mock):
requests_mock.get('https://api-a.com/')
requests.get('https://api-b.com/')
assert requests.get('https://api-a.com/')
Run Code Online (Sandbox Code Playgroud)
我正在使用pytest、requests-mock和pytest-mock作为 API 端点编写集成测试。在幕后,这个端点对我需要模拟的不同第三方 API 进行了多次调用。
其中一些调用可以被 嘲笑requests_mock。但其中一些不能,因为它们是从第三方模块内部进行调用的。
我尝试用pytest-mockmock最后一个发现它基本上不起作用。
requests_mock仍在尝试模拟该调用并抛出下一个错误:
requests_mock.exceptions.NoMockAddress: No mock address: GET https://api-b.com/
我目前想要测试以下基本 Python 类:
class Example:
def run_steps(self):
self.steps = 0
while self.steps < 4:
self.step()
def step(self):
# some expensive API call
print("wasting time...")
time.sleep(1000)
self.steps += 1
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,step() 方法包含一个昂贵的 API 调用,因此我想用另一个函数来模拟它,该函数可以避免昂贵的 API 调用,但仍然会递增self.steps。我发现这样做是可能的(从这里可以看出):
def mock_step(self):
print("skip the wasting time")
self.steps += 1
# This code works!
def test(mocker):
example = Example()
mocker.patch.object(Example, 'step', mock_step)
example.run_steps()
Run Code Online (Sandbox Code Playgroud)
我只是创建一个名为 的函数mock_step(self)来避免 API 调用,然后step()用新mock_step(self)函数修补原来的慢速方法。
然而,这导致了新的问题。由于该mock_step(self)函数不是 Mock 对象,因此我无法调用其上的任何 Mock 方法(例如 assert_used() 和 call_count()): …
python unit-testing mocking python-unittest.mock pytest-mock
pytest-mock 修补未按预期工作。我的代码:
utils.py:
def my_func():
return 42
Run Code Online (Sandbox Code Playgroud)
classes.py:
from utils import my_func
class MyClass:
def class_method(self):
return my_func()
Run Code Online (Sandbox Code Playgroud)
test_classes.py:
import pytest
from classes import MyClass
def test_myclass(mocker):
mocker.patch("utils.my_func", return_value=21)
assert MyClass().class_method() == 21
Run Code Online (Sandbox Code Playgroud)
失败了,返回的是42而不是21。
如何创建一个模拟的 mongo db 对象来使用 python 测试我的软件?
我尝试了https://pytest-mock-resources.readthedocs.io/en/latest/mongo.html但出现错误。
首先,我尝试了下面的代码:
def insert_into_customer(mongodb_connection):
collection = mongodb_connection['customer']
to_insert = {"name": "John", "address": "Highway 37"}
collection.insert_one(to_insert)
from pytest_mock_resources import create_mongo_fixture
mongo = create_mongo_fixture()
def test_insert_into_customer(mongo):
insert_into_customer(mongo)
collection = mongo['customer']
returned = collection.find_one()
assert returned == {"name": "John", "address": "Highway 37"}
test_insert_into_customer(mongo)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Traceback (most recent call last):
File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 19, in <module>
test_insert_into_customer(mongo)
File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 11, in test_insert_into_customer
insert_into_customer(mongo)
File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 2, in insert_into_customer
collection = mongodb_connection['customer']
TypeError: 'function' object …Run Code Online (Sandbox Code Playgroud) 全部,
我有一个类似的课程。
from mod import Bar
class Foo:
def __init__(self):
self.obj = Bar()
Run Code Online (Sandbox Code Playgroud)
如何Bar使用 pytest / pytest-mock 模拟构造函数?我尝试了以下失败。
def test():
with mock.patch('mod.Bar') as patched:
Foo()
Run Code Online (Sandbox Code Playgroud) 我正在使用 azure-devOps python 模块访问 azure API 以检索一些信息。我已使用以下代码来设置建立连接所需的身份验证。
def retrieve_projects_from_organization(self):
credentials = BasicAuthentication('', AZURE_PRIVATE_TOKEN)
self.azure_connection = Connection(base_url=os.environ.get('AZURE_BASE_URL',''),creds=credentials)
core_client = self.azure_connection.clients_v6_0.get_core_client()
project_list = []
projects_response = core_client.get_projects()
while projects_response is not None:
for project in projects_response:
project_list.append(project)
Run Code Online (Sandbox Code Playgroud)
在编写单元测试用例时,我无法模拟 Connection 类,因为它需要 BasicAuthentication 类型的对象。以下是我的单元测试用例:
def test_retrieve_projects_from_organization(mocker):
credentials = mocker.patch('msrest.authentication. BasicAuthentication')).return_value
connection = mocker.patch('azure.devops.connection.Connection').return_value
core_client = mocker.patch('azure.devops.v6_0.core.CoreClient').return_value
projects = mocker.patch('azure.devops.v6_0.core.TeamProjectReference').return_value
connection._creds = type(credentials)
connection.clients_v6_0.get_core_client.return_value = core_client
core_client.get_projects.return_value = [projects]
assert AzureDataFetcher().retrieve_projects_from_organization() == [projects]
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
类型错误:super() 参数 1 必须是类型,而不是 MagicMock
是否有不同的方法来模拟此类或绕过 API 身份验证的方法。