如何使用 pytest_mock 模拟从另一个 class 调用的 class 方法
How to mock a class method that is called from another class with pytest_mock
在下面的文件中我有
InternalDogWebhookResource
调用 VisitOrchestrator.fetch_visit
。我正在尝试为 InternalDogWebhookResource
编写测试,但模拟 VisitOrchestrator.fetch_visit
因为它是网络调用。
我试过模拟路径:
api.dog.handlers.internal.VisitOrchestrator.fetch_visit
api.dog.handlers.internal.InternalDogWebhookResource.VisitOrchestrator.fetch_visit
api.dog.handlers.internal.InternalDogWebhookResource.fetch_visit
和许多其他人,但我总是得到 AssertionError: assert None
我可以确认测试中的 client.post
有效,因为当我删除模拟断言时,我从 api 得到响应,这意味着 fetch_visit
被调用。
如何找到 mocker.patch
路径?
api/dog/handlers/internal.py
from api.dog.helpers.visits import VisitOrchestrator
@api.route("/internal/dog/webhook")
class InternalDogWebhookResource():
def post(self) -> JsonResponse:
if event_type == EventType.CHANGE:
VisitOrchestrator.fetch_visit(event['visitId'])
return JsonResponse(status=204)
api/dog/helpers/visits.py
class VisitOrchestrator:
@classmethod
def fetch_visit(cls, visit_id: str) -> VisitModel:
# do stuff
return visit
tests/v0/dog/handlers/test_webhook.py
import pytest
from pytest_mock import MockerFixture
from api.dog.handlers.internal import InternalDogWebhookResource, EventType
from tests.v0.utils import url_for
def test_webhook_valid(client, config, mocker: MockerFixture):
visit_id = '1231231'
mock_object = mocker.patch(
'api.dog.handlers.internal.VisitOrchestrator.fetch_visit',
return_value=visit_id,
)
res = client.post(
url_for(InternalDogWebhookResource),
json={'blag': 'blargh'}
)
assert mock_object.assert_called_once()
你做的是对的 - 你的第二种方法通常是模拟的方式(模拟 api.dog.handlers.internal.InternalDogWebhookResource.VisitOrchestrator.fetch_visit
)
我会尝试做最小的测试代码功能:
def test_webhook_valid(mocker):
mock_fetch_visit = mocker.MagicMock(name='fetch_visit')
mocker.patch('api.dog.handlers.internal.VisitOrchestrator.fetch_visit',
new=mock_fetch_visit)
InternalDogWebhookResource().post()
assert 1 == mock_fetch_visit.call_count
如果这对您有用 - 可能问题出在 client
或您的测试方法中的其他设置。
在下面的文件中我有
InternalDogWebhookResource
调用 VisitOrchestrator.fetch_visit
。我正在尝试为 InternalDogWebhookResource
编写测试,但模拟 VisitOrchestrator.fetch_visit
因为它是网络调用。
我试过模拟路径:
api.dog.handlers.internal.VisitOrchestrator.fetch_visit
api.dog.handlers.internal.InternalDogWebhookResource.VisitOrchestrator.fetch_visit
api.dog.handlers.internal.InternalDogWebhookResource.fetch_visit
和许多其他人,但我总是得到 AssertionError: assert None
我可以确认测试中的 client.post
有效,因为当我删除模拟断言时,我从 api 得到响应,这意味着 fetch_visit
被调用。
如何找到 mocker.patch
路径?
api/dog/handlers/internal.py
from api.dog.helpers.visits import VisitOrchestrator
@api.route("/internal/dog/webhook")
class InternalDogWebhookResource():
def post(self) -> JsonResponse:
if event_type == EventType.CHANGE:
VisitOrchestrator.fetch_visit(event['visitId'])
return JsonResponse(status=204)
api/dog/helpers/visits.py
class VisitOrchestrator:
@classmethod
def fetch_visit(cls, visit_id: str) -> VisitModel:
# do stuff
return visit
tests/v0/dog/handlers/test_webhook.py
import pytest
from pytest_mock import MockerFixture
from api.dog.handlers.internal import InternalDogWebhookResource, EventType
from tests.v0.utils import url_for
def test_webhook_valid(client, config, mocker: MockerFixture):
visit_id = '1231231'
mock_object = mocker.patch(
'api.dog.handlers.internal.VisitOrchestrator.fetch_visit',
return_value=visit_id,
)
res = client.post(
url_for(InternalDogWebhookResource),
json={'blag': 'blargh'}
)
assert mock_object.assert_called_once()
你做的是对的 - 你的第二种方法通常是模拟的方式(模拟 api.dog.handlers.internal.InternalDogWebhookResource.VisitOrchestrator.fetch_visit
)
我会尝试做最小的测试代码功能:
def test_webhook_valid(mocker):
mock_fetch_visit = mocker.MagicMock(name='fetch_visit')
mocker.patch('api.dog.handlers.internal.VisitOrchestrator.fetch_visit',
new=mock_fetch_visit)
InternalDogWebhookResource().post()
assert 1 == mock_fetch_visit.call_count
如果这对您有用 - 可能问题出在 client
或您的测试方法中的其他设置。