【问题标题】:In Python, is it possible to mock requests inside another request?在 Python 中,是否可以在另一个请求中模拟请求?
【发布时间】:2019-09-08 20:44:52
【问题描述】:

在 Django 中,我有一个向外部 API 发出请求的视图。视图在 my_app 中。

class ExternalAPIView(View):
    def get(self, request, *args, **kwargs):
        ...
        external_api_response = requests.get(settings.EXTERNAL_API_URL)
        ...

对于它的单元测试,我将以下函数用于@patch 装饰器的 side_effect 参数。

def mocked_requests_get_for_external_api(*args, **kwargs):
    class MockResponse:
        def __init__(self, content, status_code):
            self.content = content
            self.status_code = status_code

    if args[0] == settings.EXTERNAL_API_URL:
        return MockResponse(json.dumps('{"value": 1}'), 200)

    return MockResponse(None, 404)

...单元测试是这样进行的,没有问题:

@patch("my_app.views.requests.get", side_effect= mocked_requests_get_for_external_api)
def test_external_api(self, mock_get):
    response = self.client.get(settings.EXTERNAL_API_VIEW_URL)
    assert response.status_code == 200
    data = json.loads(response.content)
    assert data["value"] == 1

但是,我在同一个项目中有另一个视图,它调用这个 ExternalAPIView 如下:

class MainView(View):
    def get(self, request, *args, **kwargs):
        ...
        response = requests.get(request.build_absolute_uri(settings.EXTERNAL_API_VIEW_URL))
        ...

我想为此 MainView 创建一个单元测试,它将通过 settings.EXTERNAL_API_VIEW_URL 调用 ExternalAPIView,但在 ExternalAPIView 内模拟外部 API 调用。

一开始有可能吗?如果是这样,我该怎么做?

【问题讨论】:

  • 通过单元测试,你应该测试你的代码实现。您的 MainView 不调用 ExternalAPIView,因此您不应模拟 对 ExternalAPIView 的调用。所以,要么我错过了什么,要么你没有解释你真正想要什么。
  • 感谢@ipaleka 的回复。 MainView 向 EXTERNAL_API_VIEW_URL 地址发出请求,该地址执行 ExternalAPIView。 ExternalAPIView 向 EXTERNAL_API_URL 发出请求。我想模拟对EXTERNAL_API_URL 的最后一次调用。抱歉命名混乱。

标签: python django mocking django-unittest


【解决方案1】:

这可以通过仅模拟对requests.get 的第二次调用并保持第一次调用不变来实现,例如:

import requests

@patch("my_app.views.requests.get", side_effect=[requests.get, mocked_requests_get_for_external_api])
def test_main_view_api(self, mock_get):
    response = self.client.get(MAIN_VIEW_URL)
    assert response.status_code == 200
    data = json.loads(response.content)
    assert data["value"] == 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 2022-01-08
    相关资源
    最近更新 更多