如何使用requests-mock检查GET查询参数?

huangapple go评论81阅读模式
英文:

How to check GET-query-parameters with requests-mock?

问题

我有一个函数,它使用参数字典进行GET请求。在我的单元测试中,我想确保参数设置正确。然而,当我尝试使用 requests-mock 模拟请求时,我只能检查URL而不包括参数。似乎 requests-mock 没有捕获参数。

示例代码:

import requests as req

def make_request():
    url = "mock://some.url/media"
    headers = {"Authorization": "Bearer ..."}
    params = {"since": 0, "until": 1}
    req.get(url, params=params, headers=self.headers, timeout=30)

示例测试:

import requests_mock

def my_test():
    auth_headers = {"Authorization": "Bearer ..."}
    query_params = "?since=0&until=1"
    expected_url = f"mock://some.url/media{query_params}" # no mock address
    with requests_mock.Mocker() as mocker:
        mocker.get(
            expected_url,
            headers=auth_headers,
            text="media_found",
        )
        response = make_request()
        assert response.text == "media_found"
        # assert mocker.last_request.params == query_params

这对我来说是有意义的。然而,只要我在 expected_url 中使用 query_params,我就会收到 No Mock Address 错误。

当我在测试中使用不带 query_params 的URL时,测试可以正常运行,但无法检查查询参数是否正确设置。我在文档中找到了 query-string-matcher,但无法使其工作。一直出现 No Mock Address 错误。

我还尝试调试 requests-mock 提供的 request_history 对象,但其中没有设置 params/query 字段。

_url_parts: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='')
_url_parts_: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='')

这让我感到惊讶,因为在代码外部进行实际请求时,参数被正确添加。

有人能指导我如何使用 requests-mock 检查GET查询参数,而不是在 req.get() 函数上创建间谍并检查调用该函数时传递的参数吗?

谢谢!

英文:

I have a function which makes a GET-request with a dict of params. In my unit-tests I want to make sure that the parameters are set correctly. However when I try to use requests-mock to mock the request, I can only check for the URL without the parameters. It seems like the params are not picked up by requests-mock.

Example Code:

import requests as req

def make_request():
    url = "mock://some.url/media"
    headers = {"Authorization": "Bearer ..."}
    params = {"since": 0, "until": 1}
    req.get(url, params=params, headers=self.headers, timeout=30)

Example Test:

import requests_mock

def my_test():
    auth_headers = {"Authorization": "Bearer ..."}
    query_params = "?since=0&until=1"
    expected_url = f"mock://some.url/media{query_params}" # no mock address
    with requests_mock.Mocker() as mocker:
        mocker.get(
            expected_url,
            headers=auth_headers,
            text="media_found",
        )
        response = make_request()
        assert response.text == "media_found"
        # assert mocker.last_request.params == query_params

This is what would've made sense to me. However, as long as I use the query_params in expected_url I get a No Mock Address error.

When I'm using the URL without the query_params the test runs fine, but doesn't check that the query params are set correctly. I found the query-string-matcher in the documentation, but didn't get it to work. The No Mock Address error kept coming up.

I also tried debugging the request_history-object provided by requests mock, but there was no params/query field set in there.

_url_parts: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='')
_url_parts_: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='')

This was surprising, because when doing the actual request outside of the code, the params are added correctly.

Can someone point me in the right direction on how I can check the GET-query-parameters with requests-mock without creating a spy on the req.get() function and checking the parameters the function was called with?

Thanks!

答案1

得分: 0

I found the problem. I'm not sure why this happens, but the qs-parameter is not filled when using mock:// as schema for the requests. It works with http:// so I changed my mocked url to http://.

Here's a minimal example:

# works with http-scheme
def test_requests_mocker():
    with requests_mock.Mocker() as m:
        url = "http://www.example.com"
        m.get(url=f"{url}/path", text="abc")
        resp = requests.get(url=f"{url}/path", params={"limit": 10})
        assert m.last_request.qs["limit"] == ["10"]

# mock-schema doesn't work -- KeyError: 'limit'
def test_requests_mocker_mock_schema():
    with requests_mock.Mocker() as m:
        url = "mock://www.example.com"
        m.get(url=f"{url}/path", text="abc")
        resp = requests.get(url=f"{url}/path", params={"limit": 10})
        assert m.last_request.qs["limit"] == ["10"]
英文:

I found the problem. I'm not sure why this happens, but the qs-parameter is not filled when using mock:// as schema for the requests. It works with http:// so I changed my mocked url to http://.

Here's an minimal example:

# works with http-schame
def test_requests_mocker():
    with requests_mock.Mocker() as m:
        url = "http://www.example.com"
        m.get(url=f"{url}/path", text="abc")
        resp = requests.get(url=f"{url}/path", params={"limit": 10})
        assert m.last_request.qs["limit"] == ["10"]

# mock-schema doesn't work -- KeyError: 'limit'
def test_requests_mocker_mock_schema():
    with requests_mock.Mocker() as m:
        url = "mock://www.example.com"
        m.get(url=f"{url}/path", text="abc")
        resp = requests.get(url=f"{url}/path", params={"limit": 10})
        assert m.last_request.qs["limit"] == ["10"]

huangapple
  • 本文由 发表于 2023年4月19日 18:04:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76053220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定