diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 99e90f2..cb7f2ff 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,6 +15,5 @@ A clear and concise description of what you expected to happen. **Steps to reproduce** ```python -def test_issue(httpx_mock): - ... +def test_issue(httpx2_mock): ... ``` diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c0ce83c..2035b2c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -62,7 +62,7 @@ jobs: with: name: python-package-distributions path: dist/ - + # astral-sh/setup-uv v8.1.0 - name: Install uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b diff --git a/CHANGELOG.md b/CHANGELOG.md index 9baea9f..6123791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,13 +80,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ```python import pytest + @pytest.mark.httpx_mock(non_mocked_hosts=["my_local_test_host"]) - def test_previous_behavior(httpx_mock): - ... + def test_previous_behavior(httpx_mock): ... + - @pytest.mark.httpx_mock(should_mock=lambda request: request.url.host not in ["my_local_test_host"]) - def test_new_behavior(httpx_mock): - ... + @pytest.mark.httpx_mock( + should_mock=lambda request: request.url.host not in ["my_local_test_host"] + ) + def test_new_behavior(httpx_mock): ... ``` Please note that your hosts might need to be prefixed with `www.` depending on your usage. @@ -136,10 +138,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Apply marker to whole module pytestmark = pytest.mark.httpx_mock(assert_all_responses_were_requested=False) + # Or to specific tests @pytest.mark.httpx_mock(non_mocked_hosts=[...]) - def test_foo(httpx_mock): - ... + def test_foo(httpx_mock): ... ``` - The following options are available: - `assert_all_responses_were_requested` (boolean), defaulting to `True`. diff --git a/README.md b/README.md index a79742d..5c2bfd5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## HTTPX2 mocking options -**httpx2-pytest** (this project) builds on the design and API of **[pytest-httpx](https://github.com/Colin-b/pytest_httpx)** by [Colin Bounouar](https://github.com/Colin-b) — the established pytest plugin for mocking [HTTPX](https://www.python-httpx.org). That project defined the `httpx_mock` fixture and request-matching model many test suites already rely on. This fork carries that approach forward for [HTTPX2](https://github.com/pydantic/httpx2) and aims to stay compatible with pytest-httpx: same fixture names, markers, and `httpx_mock.add_response` / `add_callback` patterns so you can migrate from HTTPX with minimal test changes. +**httpx2-pytest** (this project) builds on the design and API of **[pytest-httpx](https://github.com/Colin-b/pytest_httpx)** by [Colin Bounouar](https://github.com/Colin-b) — the established pytest plugin for mocking [HTTPX](https://www.python-httpx.org). That project defined the `httpx_mock` fixture and request-matching model many test suites already rely on. This fork carries that approach forward for [HTTPX2](https://github.com/pydantic/httpx2), keeping the same matching model, marker options, and `add_response` / `add_callback` patterns. The fixture and marker are named `httpx2_mock` rather than `httpx_mock` so that both plugins can be installed at once. **[pytest-httpx2](https://github.com/lundberg/pytest-httpx2)** by [Erik Lundberg](https://github.com/lundberg) is another HTTPX2 option, built on [respx](https://github.com/lundberg/respx). It is **not** a drop-in replacement for pytest-httpx — the API and configuration differ from Colin’s plugin. Choose it if you prefer respx-style routing; choose **httpx2-pytest** if you want pytest-httpx–like behavior on HTTPX2. @@ -30,16 +30,16 @@ import httpx2 response = httpx2.get("https://www.example.org/") ``` -**httpx2-pytest** patches HTTPX2 transports so your tests never hit the network unless you opt out. Use `import httpx2` in your application and test code; the `httpx_mock` fixture intercepts `httpx2.Client` and `httpx2.AsyncClient` requests the same way pytest-httpx did for HTTPX. +**httpx2-pytest** patches HTTPX2 transports so your tests never hit the network unless you opt out. Use `import httpx2` in your application and test code; the `httpx2_mock` fixture intercepts `httpx2.Client` and `httpx2.AsyncClient` requests the same way pytest-httpx's `httpx_mock` did for HTTPX. ```shell pip install httpx2-pytest ``` > [!NOTE] -> This project targets [HTTPX2](https://github.com/pydantic/httpx2) instead of HTTPX, in the spirit of [pytest-httpx](https://github.com/Colin-b/pytest_httpx). The mocking API and `httpx_mock` fixture name are unchanged for compatibility with existing test suites. +> This project targets [HTTPX2](https://github.com/pydantic/httpx2) instead of HTTPX, in the spirit of [pytest-httpx](https://github.com/Colin-b/pytest_httpx). The mocking API is unchanged; the fixture and marker are named `httpx2_mock` so they never clash with pytest-httpx's `httpx_mock`, letting both plugins live in the same test suite. -Once installed, the `httpx_mock` or `httpx2_mock` [`pytest`](https://docs.pytest.org/en/latest/) fixture will make sure every [`httpx2`](https://httpx2.pydantic.dev) request will be replied to with user provided responses ([unless some hosts are explicitly skipped](#do-not-mock-some-requests)). Both fixtures share the same implementation. +Once installed, the `httpx2_mock` [`pytest`](https://docs.pytest.org/en/latest/) fixture will make sure every [`httpx2`](https://httpx2.pydantic.dev) request will be replied to with user provided responses ([unless some hosts are explicitly skipped](#do-not-mock-some-requests)). - [Add responses](#add-responses) - [JSON body](#add-json-response) @@ -51,12 +51,13 @@ Once installed, the `httpx_mock` or `httpx2_mock` [`pytest`](https://docs.pytest - [Add dynamic responses](#dynamic-responses) - [Raising exceptions](#raising-exceptions) - [Check requests](#check-sent-requests) -- [Configuration](#configuring-httpx_mock) +- [Configuration](#configuring-httpx2_mock) - [Register more responses than requested](#allow-to-register-more-responses-than-what-will-be-requested) - [Register less responses than requested](#allow-to-not-register-responses-for-every-request) - [Allow to register a response for more than one request](#allow-to-register-a-response-for-more-than-one-request) - [Do not mock some requests](#do-not-mock-some-requests) - [Migrating](#migrating-to-httpx2-pytest) + - [pytest-httpx](#from-pytest-httpx) - [responses](#from-responses) - [aioresponses](#from-aioresponses) @@ -69,16 +70,16 @@ import pytest import httpx2 -def test_something(httpx_mock): - httpx_mock.add_response() +def test_something(httpx2_mock): + httpx2_mock.add_response() with httpx2.Client() as client: response = client.get("https://test_url") @pytest.mark.asyncio -async def test_something_async(httpx_mock): - httpx_mock.add_response() +async def test_something_async(httpx2_mock): + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -110,23 +111,25 @@ import re from pytest_httpx2 import HTTPXMock -def test_url(httpx_mock: HTTPXMock): - httpx_mock.add_response(url="https://test_url?a=1&b=2") +def test_url(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url="https://test_url?a=1&b=2") with httpx2.Client() as client: response1 = client.delete("https://test_url?a=1&b=2") response2 = client.get("https://test_url?b=2&a=1") -def test_url_as_pattern(httpx_mock: HTTPXMock): - httpx_mock.add_response(url=re.compile(".*test.*")) +def test_url_as_pattern(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url=re.compile(".*test.*")) with httpx2.Client() as client: response = client.get("https://test_url") -def test_url_as_httpx2_url(httpx_mock: HTTPXMock): - httpx_mock.add_response(url=httpx2.URL("https://test_url", params={"a": "1", "b": "2"})) +def test_url_as_httpx2_url(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + url=httpx2.URL("https://test_url", params={"a": "1", "b": "2"}) + ) with httpx2.Client() as client: response = client.get("https://test_url?a=1&b=2") @@ -142,8 +145,8 @@ import re from pytest_httpx2 import HTTPXMock -def test_url_as_pattern_ignoring_query_parameters(httpx_mock: HTTPXMock): - httpx_mock.add_response(url=re.compile("https://test_url/something.*")) +def test_url_as_pattern_ignoring_query_parameters(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url=re.compile("https://test_url/something.*")) with httpx2.Client() as client: response = client.get("https://test_url/something?a=1&b=2") @@ -163,14 +166,18 @@ import httpx2 from pytest_httpx2 import HTTPXMock from unittest.mock import ANY -def test_partial_params_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(url="https://test_url", match_params={"a": 1, "b": ANY}) + +def test_partial_params_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url="https://test_url", match_params={"a": 1, "b": ANY}) with httpx2.Client() as client: response = client.get("https://test_url?a=1&b=2") -def test_partial_multi_params_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(url="https://test_url", match_params={"a": ["1", 3], "b": ["2", ANY]}) + +def test_partial_multi_params_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + url="https://test_url", match_params={"a": ["1", 3], "b": ["2", ANY]} + ) with httpx2.Client() as client: response = client.get("https://test_url?a=1&b=2&a=3&b=4") @@ -189,40 +196,39 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_post(httpx_mock: HTTPXMock): - httpx_mock.add_response(method="POST") +def test_post(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(method="POST") with httpx2.Client() as client: response = client.post("https://test_url") -def test_put(httpx_mock: HTTPXMock): - httpx_mock.add_response(method="PUT") +def test_put(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(method="PUT") with httpx2.Client() as client: response = client.put("https://test_url") -def test_delete(httpx_mock: HTTPXMock): - httpx_mock.add_response(method="DELETE") +def test_delete(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(method="DELETE") with httpx2.Client() as client: response = client.delete("https://test_url") -def test_patch(httpx_mock: HTTPXMock): - httpx_mock.add_response(method="PATCH") +def test_patch(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(method="PATCH") with httpx2.Client() as client: response = client.patch("https://test_url") -def test_head(httpx_mock: HTTPXMock): - httpx_mock.add_response(method="HEAD") +def test_head(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(method="HEAD") with httpx2.Client() as client: response = client.head("https://test_url") - ``` #### Matching on proxy URL @@ -238,8 +244,8 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_proxy_url(httpx_mock: HTTPXMock): - httpx_mock.add_response(proxy_url="http://test_proxy_url?b=1&a=2") +def test_proxy_url(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(proxy_url="http://test_proxy_url?b=1&a=2") with httpx2.Client(proxy="http://test_proxy_url?a=2&b=1") as client: response = client.get("https://test_url") @@ -256,8 +262,8 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_headers_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_headers={'User-Agent': 'python-httpx2/2.2.0'}) +def test_headers_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(match_headers={"User-Agent": "python-httpx2/2.2.0"}) with httpx2.Client() as client: response = client.get("https://test_url") @@ -274,8 +280,8 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_content_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_content=b"This is the body") +def test_content_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(match_content=b"This is the body") with httpx2.Client() as client: response = client.post("https://test_url", content=b"This is the body") @@ -292,15 +298,16 @@ import httpx2 from pytest_httpx2 import HTTPXMock from unittest.mock import ANY -def test_json_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_json={"a": "json", "b": 2}) + +def test_json_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(match_json={"a": "json", "b": 2}) with httpx2.Client() as client: response = client.post("https://test_url", json={"a": "json", "b": 2}) -def test_partial_json_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_json={"a": "json", "b": ANY}) +def test_partial_json_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(match_json={"a": "json", "b": ANY}) with httpx2.Client() as client: response = client.post("https://test_url", json={"a": "json", "b": 2}) @@ -318,11 +325,19 @@ Matching is performed on equality. import httpx2 from pytest_httpx2 import HTTPXMock -def test_multipart_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}) + +def test_multipart_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + match_files={"name": ("file_name", b"File content")}, + match_data={"field": "value"}, + ) with httpx2.Client() as client: - response = client.post("https://test_url", files={"name": ("file_name", b"File content")}, data={"field": "value"}) + response = client.post( + "https://test_url", + files={"name": ("file_name", b"File content")}, + data={"field": "value"}, + ) ``` Note that `match_content` or `match_json` cannot be provided if `match_files` is also provided. @@ -338,8 +353,8 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_extensions_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_extensions={'test': 'value'}) +def test_extensions_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(match_extensions={"test": "value"}) with httpx2.Client() as client: response = client.get("https://test_url", extensions={"test": "value"}) @@ -356,8 +371,12 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_timeout_matching(httpx_mock: HTTPXMock): - httpx_mock.add_response(match_extensions={'timeout': {'connect': 10, 'read': 10, 'write': 10, 'pool': 10}}) +def test_timeout_matching(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + match_extensions={ + "timeout": {"connect": 10, "read": 10, "write": 10, "pool": 10} + } + ) with httpx2.Client() as client: response = client.get("https://test_url", timeout=10) @@ -372,12 +391,13 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_json(httpx_mock: HTTPXMock): - httpx_mock.add_response(json=[{"key1": "value1", "key2": "value2"}]) +def test_json(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(json=[{"key1": "value1", "key2": "value2"}]) with httpx2.Client() as client: - assert client.get("https://test_url").json() == [{"key1": "value1", "key2": "value2"}] - + assert client.get("https://test_url").json() == [ + {"key1": "value1", "key2": "value2"} + ] ``` Note that the `content-type` header will be set to `application/json` by default in the response. @@ -391,12 +411,11 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_str_body(httpx_mock: HTTPXMock): - httpx_mock.add_response(text="This is my UTF-8 content") +def test_str_body(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(text="This is my UTF-8 content") with httpx2.Client() as client: assert client.get("https://test_url").text == "This is my UTF-8 content" - ``` Use `content` parameter to reply with a custom body by providing bytes. @@ -406,12 +425,11 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_bytes_body(httpx_mock: HTTPXMock): - httpx_mock.add_response(content=b"This is my bytes content") +def test_bytes_body(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(content=b"This is my bytes content") with httpx2.Client() as client: assert client.get("https://test_url").content == b"This is my bytes content" - ``` Use `html` parameter to reply with a custom body by providing UTF-8 encoded string. @@ -421,12 +439,14 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_html_body(httpx_mock: HTTPXMock): - httpx_mock.add_response(html="
This isHTML content") +def test_html_body(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(html="
This isHTML content") with httpx2.Client() as client: - assert client.get("https://test_url").text == "
This isHTML content" - + assert ( + client.get("https://test_url").text + == "
This isHTML content" + ) ``` ### Reply by streaming chunks @@ -440,8 +460,9 @@ import httpx2 import pytest from pytest_httpx2 import HTTPXMock, IteratorStream -def test_sync_streaming(httpx_mock: HTTPXMock): - httpx_mock.add_response(stream=IteratorStream([b"part 1", b"part 2"])) + +def test_sync_streaming(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(stream=IteratorStream([b"part 1", b"part 2"])) with httpx2.Client() as client: with client.stream(method="GET", url="https://test_url") as response: @@ -449,13 +470,15 @@ def test_sync_streaming(httpx_mock: HTTPXMock): @pytest.mark.asyncio -async def test_async_streaming(httpx_mock: HTTPXMock): - httpx_mock.add_response(stream=IteratorStream([b"part 1", b"part 2"])) +async def test_async_streaming(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(stream=IteratorStream([b"part 1", b"part 2"])) async with httpx2.AsyncClient() as client: async with client.stream(method="GET", url="https://test_url") as response: - assert [part async for part in response.aiter_raw()] == [b"part 1", b"part 2"] - + assert [part async for part in response.aiter_raw()] == [ + b"part 1", + b"part 2", + ] ``` ### Add multipart response @@ -470,11 +493,19 @@ from httpx2._multipart import MultipartStream from pytest_httpx2 import HTTPXMock -def test_multipart_body(httpx_mock: HTTPXMock): - httpx_mock.add_response(stream=MultipartStream(data={"key1": "value1"}, files={"file1": b"content of file 1"}, boundary=b"2256d3a36d2a61a1eba35a22bee5c74a")) +def test_multipart_body(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + stream=MultipartStream( + data={"key1": "value1"}, + files={"file1": b"content of file 1"}, + boundary=b"2256d3a36d2a61a1eba35a22bee5c74a", + ) + ) with httpx2.Client() as client: - assert client.get("https://test_url").text == '''--2256d3a36d2a61a1eba35a22bee5c74a\r + assert ( + client.get("https://test_url").text + == """--2256d3a36d2a61a1eba35a22bee5c74a\r Content-Disposition: form-data; name="key1"\r \r value1\r @@ -484,8 +515,8 @@ Content-Type: application/octet-stream\r \r content of file 1\r --2256d3a36d2a61a1eba35a22bee5c74a--\r -''' - +""" + ) ``` ### Add non 200 response @@ -497,12 +528,11 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_status_code(httpx_mock: HTTPXMock): - httpx_mock.add_response(status_code=404) +def test_status_code(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(status_code=404) with httpx2.Client() as client: assert client.get("https://test_url").status_code == 404 - ``` ### Reply with custom headers @@ -516,26 +546,25 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_headers_as_str_dict(httpx_mock: HTTPXMock): - httpx_mock.add_response(headers={"X-Header1": "Test value"}) +def test_headers_as_str_dict(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(headers={"X-Header1": "Test value"}) with httpx2.Client() as client: assert client.get("https://test_url").headers["x-header1"] == "Test value" -def test_headers_as_str_tuple_list(httpx_mock: HTTPXMock): - httpx_mock.add_response(headers=[("X-Header1", "Test value")]) +def test_headers_as_str_tuple_list(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(headers=[("X-Header1", "Test value")]) with httpx2.Client() as client: assert client.get("https://test_url").headers["x-header1"] == "Test value" -def test_headers_as_httpx2_headers(httpx_mock: HTTPXMock): - httpx_mock.add_response(headers=httpx2.Headers({b"X-Header1": b"Test value"})) +def test_headers_as_httpx2_headers(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(headers=httpx2.Headers({b"X-Header1": b"Test value"})) with httpx2.Client() as client: assert client.get("https://test_url").headers["x-header1"] == "Test value" - ``` #### Reply with cookies @@ -549,21 +578,22 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_cookie(httpx_mock: HTTPXMock): - httpx_mock.add_response(headers={"set-cookie": "key=value"}) +def test_cookie(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(headers={"set-cookie": "key=value"}) with httpx2.Client() as client: response = client.get("https://test_url") assert dict(response.cookies) == {"key": "value"} -def test_cookies(httpx_mock: HTTPXMock): - httpx_mock.add_response(headers=[("set-cookie", "key=value"), ("set-cookie", "key2=value2")]) +def test_cookies(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( + headers=[("set-cookie", "key=value"), ("set-cookie", "key2=value2")] + ) with httpx2.Client() as client: response = client.get("https://test_url") assert dict(response.cookies) == {"key": "value", "key2": "value2"} - ``` @@ -576,12 +606,11 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_http_version(httpx_mock: HTTPXMock): - httpx_mock.add_response(http_version="HTTP/2.0") +def test_http_version(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(http_version="HTTP/2.0") with httpx2.Client() as client: assert client.get("https://test_url").http_version == "HTTP/2.0" - ``` ## Add callbacks @@ -593,7 +622,7 @@ Callback should expect one parameter, the received [`httpx2.Request`](https://ht If all callbacks are not executed during test execution, the test case will fail at teardown [(unless you turned `assert_all_responses_were_requested` option off)](#allow-to-register-more-responses-than-what-will-be-requested). Note that callbacks are considered as responses, and thus are [selected the same way](#how-response-is-selected). -Meaning that you can transpose `httpx_mock.add_response` calls in the related examples into `httpx_mock.add_callback`. +Meaning that you can transpose `httpx2_mock.add_response` calls in the related examples into `httpx2_mock.add_callback`. ### Dynamic responses @@ -604,18 +633,18 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_dynamic_response(httpx_mock: HTTPXMock): +def test_dynamic_response(httpx2_mock: HTTPXMock): def custom_response(request: httpx2.Request): return httpx2.Response( - status_code=200, json={"url": str(request.url)}, + status_code=200, + json={"url": str(request.url)}, ) - httpx_mock.add_callback(custom_response) + httpx2_mock.add_callback(custom_response) with httpx2.Client() as client: response = client.get("https://test_url") assert response.json() == {"url": "https://test_url"} - ``` Alternatively, callbacks can also be asynchronous. @@ -630,29 +659,29 @@ from pytest_httpx2 import HTTPXMock @pytest.mark.asyncio -async def test_dynamic_async_response(httpx_mock: HTTPXMock): +async def test_dynamic_async_response(httpx2_mock: HTTPXMock): async def simulate_network_latency(request: httpx2.Request): await asyncio.sleep(1) return httpx2.Response( - status_code=200, json={"url": str(request.url)}, + status_code=200, + json={"url": str(request.url)}, ) - httpx_mock.add_callback(simulate_network_latency) - httpx_mock.add_response() + httpx2_mock.add_callback(simulate_network_latency) + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: responses = await asyncio.gather( # Response will be received after one second client.get("https://test_url"), # Response will instantly be received (1 second before the first request) - client.get("https://test_url") + client.get("https://test_url"), ) - ``` ### Raising exceptions -You can simulate HTTPX2 exception throwing by raising an exception in your callback or use `httpx_mock.add_exception` with the exception instance. +You can simulate HTTPX2 exception throwing by raising an exception in your callback or use `httpx2_mock.add_exception` with the exception instance. This can be useful if you want to assert that your code handles HTTPX2 exceptions properly. @@ -662,13 +691,12 @@ import pytest from pytest_httpx2 import HTTPXMock -def test_exception_raising(httpx_mock: HTTPXMock): - httpx_mock.add_exception(httpx2.ReadTimeout("Unable to read within timeout")) +def test_exception_raising(httpx2_mock: HTTPXMock): + httpx2_mock.add_exception(httpx2.ReadTimeout("Unable to read within timeout")) with httpx2.Client() as client: with pytest.raises(httpx2.ReadTimeout): client.get("https://test_url") - ``` #### In case no response can be found @@ -683,12 +711,11 @@ import pytest from pytest_httpx2 import HTTPXMock -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_timeout(httpx_mock: HTTPXMock): +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_timeout(httpx2_mock: HTTPXMock): with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException): client.get("https://test_url") - ``` ## Check sent requests @@ -705,27 +732,27 @@ import httpx2 from pytest_httpx2 import HTTPXMock -def test_many_requests(httpx_mock: HTTPXMock): - httpx_mock.add_response() +def test_many_requests(httpx2_mock: HTTPXMock): + httpx2_mock.add_response() with httpx2.Client() as client: response1 = client.get("https://test_url") response2 = client.get("https://test_url") - requests = httpx_mock.get_requests() + requests = httpx2_mock.get_requests() -def test_single_request(httpx_mock: HTTPXMock): - httpx_mock.add_response() +def test_single_request(httpx2_mock: HTTPXMock): + httpx2_mock.add_response() with httpx2.Client() as client: response = client.get("https://test_url") - request = httpx_mock.get_request() + request = httpx2_mock.get_request() -def test_no_request(httpx_mock: HTTPXMock): - assert not httpx_mock.get_request() +def test_no_request(httpx2_mock: HTTPXMock): + assert not httpx2_mock.get_request() ``` ### How requests are selected @@ -733,11 +760,11 @@ def test_no_request(httpx_mock: HTTPXMock): You can add criteria so that requests will be returned only in case of a more specific matching. Note that requests are [selected the same way as responses](#how-response-is-selected). -Meaning that you can transpose `httpx_mock.add_response` calls in the related examples into `httpx_mock.get_requests` or `httpx_mock.get_request`. +Meaning that you can transpose `httpx2_mock.add_response` calls in the related examples into `httpx2_mock.get_requests` or `httpx2_mock.get_request`. -## Configuring httpx_mock +## Configuring httpx2_mock -The `httpx_mock` marker is available and can be used to change the default behavior of the `httpx_mock` fixture. +The `httpx2_mock` marker is available and can be used to change the default behavior of the `httpx2_mock` fixture. Refer to [available options](#available-options) for an exhaustive list of options that can be set [per test](#per-test), [per module](#per-module) or even [on the whole test suite](#for-the-whole-test-suite). @@ -746,9 +773,9 @@ Refer to [available options](#available-options) for an exhaustive list of optio ```python import pytest -@pytest.mark.httpx_mock(assert_all_responses_were_requested=False) -def test_something(httpx_mock): - ... + +@pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) +def test_something(httpx2_mock): ... ``` ### Per module @@ -756,7 +783,7 @@ def test_something(httpx_mock): ```python import pytest -pytestmark = pytest.mark.httpx_mock(assert_all_responses_were_requested=False) +pytestmark = pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) ``` ### For the whole test suite @@ -765,9 +792,12 @@ This should be set in the root `conftest.py` file. ```python import pytest + def pytest_collection_modifyitems(session, config, items): for item in items: - item.add_marker(pytest.mark.httpx_mock(assert_all_responses_were_requested=False)) + item.add_marker( + pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) + ) ``` > [!IMPORTANT] @@ -788,14 +818,14 @@ By default, `httpx2-pytest` will ensure that every response was requested during If you want to add an optional response, you can use the `is_optional` parameter when [registering a response](#add-responses) or [a callback](#add-callbacks). ```python -def test_fewer_requests_than_expected(httpx_mock): +def test_fewer_requests_than_expected(httpx2_mock): # Even if this response never received a corresponding request, the test will not fail at teardown - httpx_mock.add_response(is_optional=True) + httpx2_mock.add_response(is_optional=True) ``` If you don't have control over the response registration process (shared fixtures), and you want to allow fewer requests than what you registered responses for, -you can use the `httpx_mock` marker `assert_all_responses_were_requested` option. +you can use the `httpx2_mock` marker `assert_all_responses_were_requested` option. > [!CAUTION] > Use this option at your own risk of not spotting regression (requests not sent) in your code base! @@ -803,10 +833,11 @@ you can use the `httpx_mock` marker `assert_all_responses_were_requested` option ```python import pytest -@pytest.mark.httpx_mock(assert_all_responses_were_requested=False) -def test_fewer_requests_than_expected(httpx_mock): + +@pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) +def test_fewer_requests_than_expected(httpx2_mock): # Even if this response never received a corresponding request, the test will not fail at teardown - httpx_mock.add_response() + httpx2_mock.add_response() ``` Note that the `is_optional` parameter will take precedence over the `assert_all_responses_were_requested` option. @@ -815,17 +846,18 @@ Meaning you can still register a response that will be checked for execution at ```python import pytest -@pytest.mark.httpx_mock(assert_all_responses_were_requested=False) -def test_force_expected_request(httpx_mock): + +@pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) +def test_force_expected_request(httpx2_mock): # Even if the assert_all_responses_were_requested option is set, the test will fail at teardown if this is not matched - httpx_mock.add_response(is_optional=False) + httpx2_mock.add_response(is_optional=False) ``` #### Allow to not register responses for every request By default, `httpx2-pytest` will ensure that every request that was issued was expected. -You can use the `httpx_mock` marker `assert_all_requests_were_expected` option to allow more requests than what you registered responses for. +You can use the `httpx2_mock` marker `assert_all_requests_were_expected` option to allow more requests than what you registered responses for. > [!CAUTION] > Use this option at your own risk of not spotting regression (unexpected requests) in your code base! @@ -834,8 +866,9 @@ You can use the `httpx_mock` marker `assert_all_requests_were_expected` option t import pytest import httpx2 -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_more_requests_than_expected(httpx_mock): + +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_more_requests_than_expected(httpx2_mock): with httpx2.Client() as client: # Even if this request was not expected, the test will not fail at teardown with pytest.raises(httpx2.TimeoutException): @@ -851,8 +884,9 @@ If you want to add a response once, while allowing it to match more than once, y ```python import httpx2 -def test_more_requests_than_responses(httpx_mock): - httpx_mock.add_response(is_reusable=True) + +def test_more_requests_than_responses(httpx2_mock): + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url") # Even if only one response was registered, the test will not fail at teardown as this request will also be matched @@ -861,7 +895,7 @@ def test_more_requests_than_responses(httpx_mock): If you don't have control over the response registration process (shared fixtures), and you want to allow multiple requests to match the same registered response, -you can use the `httpx_mock` marker `can_send_already_matched_responses` option. +you can use the `httpx2_mock` marker `can_send_already_matched_responses` option. With this option, in case all matching responses have been sent at least once, the last one (according to the registration order) will be sent. @@ -872,9 +906,10 @@ With this option, in case all matching responses have been sent at least once, t import pytest import httpx2 -@pytest.mark.httpx_mock(can_send_already_matched_responses=True) -def test_more_requests_than_responses(httpx_mock): - httpx_mock.add_response() + +@pytest.mark.httpx2_mock(can_send_already_matched_responses=True) +def test_more_requests_than_responses(httpx2_mock): + httpx2_mock.add_response() with httpx2.Client() as client: client.get("https://test_url") # Even if only one response was registered, the test will not fail at teardown as this request will also be matched @@ -887,7 +922,7 @@ By default, `httpx2-pytest` will mock every request. But, for instance, in case you want to write integration tests with other servers, you might want to let some requests go through. -To do so, you can use the `httpx_mock` marker `should_mock` option and provide a callable expecting the [`httpx2.Request`](https://httpx2.pydantic.dev/api/#request) as parameter and returning a boolean. +To do so, you can use the `httpx2_mock` marker `should_mock` option and provide a callable expecting the [`httpx2.Request`](https://httpx2.pydantic.dev/api/#request) as parameter and returning a boolean. Returning `True` will ensure that the request is handled by `httpx2-pytest` (mocked), `False` will let the request pass through (not mocked). @@ -895,9 +930,12 @@ Returning `True` will ensure that the request is handled by `httpx2-pytest` (moc import pytest import httpx2 -@pytest.mark.httpx_mock(should_mock=lambda request: request.url.host != "www.my_local_test_host") -def test_partial_mock(httpx_mock): - httpx_mock.add_response() + +@pytest.mark.httpx2_mock( + should_mock=lambda request: request.url.host != "www.my_local_test_host" +) +def test_partial_mock(httpx2_mock): + httpx2_mock.add_response() with httpx2.Client() as client: # This request will NOT be mocked @@ -910,13 +948,44 @@ def test_partial_mock(httpx_mock): Here is how to migrate from well-known testing libraries to `httpx2-pytest`. +### From pytest-httpx + +`httpx2-pytest` is designed to be installed **next to** [`pytest-httpx`](https://github.com/Colin-b/pytest_httpx), not instead of it, so a test suite can move from `httpx` to `httpx2` gradually. Nothing is shared between the two plugins: `httpx_mock` keeps patching `httpx` transports and `httpx2_mock` patches `httpx2` transports, and a single test can request both. + +```python +import httpx +import httpx2 + + +def test_still_on_httpx(httpx_mock): + httpx_mock.add_response(json={"key": "value"}) + + assert httpx.get("https://test_url").json() == {"key": "value"} + + +def test_already_on_httpx2(httpx2_mock): + httpx2_mock.add_response(json={"key": "value"}) + + assert httpx2.get("https://test_url").json() == {"key": "value"} + + +def test_during_the_move(httpx_mock, httpx2_mock): + httpx_mock.add_response(url="https://legacy_url") + httpx2_mock.add_response(url="https://migrated_url") + + httpx.get("https://legacy_url") + httpx2.get("https://migrated_url") +``` + +The markers are separated the same way: `@pytest.mark.httpx_mock(...)` configures pytest-httpx, `@pytest.mark.httpx2_mock(...)` configures this plugin. Options carry the same names and defaults, so porting a test is a matter of renaming the fixture, the marker and the `httpx` import. + ### From responses | Feature | responses | httpx2-pytest | |:------------------|:---------------------------|:----------------------------| -| Add a response | `responses.add()` | `httpx_mock.add_response()` | -| Add a callback | `responses.add_callback()` | `httpx_mock.add_callback()` | -| Retrieve requests | `responses.calls` | `httpx_mock.get_requests()` | +| Add a response | `responses.add()` | `httpx2_mock.add_response()` | +| Add a callback | `responses.add_callback()` | `httpx2_mock.add_callback()` | +| Retrieve requests | `responses.calls` | `httpx2_mock.get_requests()` | #### Add a response or a callback @@ -937,6 +1006,7 @@ Sample adding a response with `responses`: ```python from responses import RequestsMock + def test_response(responses: RequestsMock): responses.add( method=responses.GET, @@ -944,29 +1014,28 @@ def test_response(responses: RequestsMock): body=b"This is the response content", status=400, ) - ``` Sample adding the same response with `httpx2-pytest`: ```python from pytest_httpx2 import HTTPXMock -def test_response(httpx_mock: HTTPXMock): - httpx_mock.add_response( + +def test_response(httpx2_mock: HTTPXMock): + httpx2_mock.add_response( method="GET", url="https://test_url", content=b"This is the response content", status_code=400, ) - ``` ### From aioresponses | Feature | aioresponses | httpx2-pytest | |:---------------|:------------------------|:-------------------------------------------| -| Add a response | `aioresponses.method()` | `httpx_mock.add_response(method="METHOD")` | -| Add a callback | `aioresponses.method()` | `httpx_mock.add_callback(method="METHOD")` | +| Add a response | `aioresponses.method()` | `httpx2_mock.add_response(method="METHOD")` | +| Add a callback | `aioresponses.method()` | `httpx2_mock.add_callback(method="METHOD")` | #### Add a response or a callback @@ -998,17 +1067,15 @@ def test_response(mock_aioresponse): body=b"This is the response content", status=400, ) - ``` Sample adding the same response with `httpx2-pytest`: ```python -def test_response(httpx_mock): - httpx_mock.add_response( +def test_response(httpx2_mock): + httpx2_mock.add_response( method="GET", url="https://test_url", content=b"This is the response content", status_code=400, ) - ``` diff --git a/pytest_httpx2/__init__.py b/pytest_httpx2/__init__.py index 39d6243..68a5b00 100644 --- a/pytest_httpx2/__init__.py +++ b/pytest_httpx2/__init__.py @@ -17,21 +17,20 @@ ) -def _httpx_mock_options(request: FixtureRequest) -> _HTTPXMockOptions: - httpx_mock_markers: dict = {} - for marker_name in ("httpx_mock", "httpx2_mock"): - for marker in request.node.iter_markers(marker_name): - httpx_mock_markers = marker.kwargs | httpx_mock_markers +def _httpx2_mock_options(request: FixtureRequest) -> _HTTPXMockOptions: + httpx2_mock_markers: dict = {} + for marker in request.node.iter_markers("httpx2_mock"): + httpx2_mock_markers = marker.kwargs | httpx2_mock_markers __tracebackhide__ = methodcaller("errisinstance", TypeError) - return _HTTPXMockOptions(**httpx_mock_markers) + return _HTTPXMockOptions(**httpx2_mock_markers) @pytest.fixture -def httpx_mock( +def httpx2_mock( monkeypatch: MonkeyPatch, request: FixtureRequest, ) -> Generator[HTTPXMock, None, None]: - options = _httpx_mock_options(request) + options = _httpx2_mock_options(request) mock = HTTPXMock(options) # Mock synchronous requests @@ -73,12 +72,6 @@ async def mocked_handle_async_request( mock.reset() -@pytest.fixture -def httpx2_mock(httpx_mock: HTTPXMock) -> HTTPXMock: - """Alias of :func:`httpx_mock` for HTTPX2-oriented test suites.""" - return httpx_mock - - def pytest_configure(config: Config) -> None: marker_signature = ( "*, assert_all_responses_were_requested=True, " @@ -88,9 +81,5 @@ def pytest_configure(config: Config) -> None: ) config.addinivalue_line( "markers", - f"httpx_mock({marker_signature}): Configure httpx_mock / httpx2_mock fixtures.", - ) - config.addinivalue_line( - "markers", - f"httpx2_mock({marker_signature}): Configure httpx_mock / httpx2_mock fixtures.", + f"httpx2_mock({marker_signature}): Configure the httpx2_mock fixture.", ) diff --git a/pytest_httpx2/_httpx_mock.py b/pytest_httpx2/_httpx_mock.py index 1331699..8f14f5a 100644 --- a/pytest_httpx2/_httpx_mock.py +++ b/pytest_httpx2/_httpx_mock.py @@ -13,7 +13,7 @@ class HTTPXMock: """ - This class is only exposed for `httpx_mock` fixture type hinting purpose. + This class is only exposed for `httpx2_mock` fixture type hinting purpose. """ def __init__(self, options: _HTTPXMockOptions) -> None: diff --git a/tests/test_httpx_async.py b/tests/test_httpx_async.py index aa3ced4..83d8fab 100644 --- a/tests/test_httpx_async.py +++ b/tests/test_httpx_async.py @@ -16,8 +16,8 @@ @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_without_response(httpx_mock: HTTPXMock) -> None: +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_without_response(httpx2_mock: HTTPXMock) -> None: with pytest.raises(Exception) as exception_info: async with httpx2.AsyncClient() as client: await client.get("https://test_url") @@ -28,8 +28,8 @@ async def test_without_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_default_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +async def test_default_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -40,8 +40,8 @@ async def test_default_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") +async def test_url_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -49,8 +49,8 @@ async def test_url_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_matching_reusing_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +async def test_url_matching_reusing_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -61,8 +61,8 @@ async def test_url_matching_reusing_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_query_string_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?a=1&b=2", is_reusable=True) +async def test_url_query_string_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?a=1&b=2", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.post("https://test_url?a=1&b=2") @@ -74,8 +74,8 @@ async def test_url_query_string_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_query_params_partial_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_url_query_params_partial_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url=httpx2.URL("https://test_url"), match_params={"a": ["1", "3"], "b": ANY, "c": "4", "d": ["5", ANY], "e": [ANY]}, is_reusable=True, @@ -91,8 +91,8 @@ async def test_url_query_params_partial_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_as_pattern_ignoring_query_parameters(httpx_mock: HTTPXMock): - httpx_mock.add_response(url=re.compile("https://test_url/something.*")) +async def test_url_as_pattern_ignoring_query_parameters(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url=re.compile("https://test_url/something.*")) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url/something?a=1&b=2") @@ -100,8 +100,8 @@ async def test_url_as_pattern_ignoring_query_parameters(httpx_mock: HTTPXMock): @pytest.mark.asyncio -async def test_url_query_params_with_single_value_list(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_url_query_params_with_single_value_list(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={"a": ["1"]}, is_optional=True, @@ -113,8 +113,8 @@ async def test_url_query_params_with_single_value_list(httpx_mock: HTTPXMock) -> @pytest.mark.asyncio -async def test_url_query_params_with_non_str_name(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_url_query_params_with_non_str_name(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={1: "1"}, is_optional=True, @@ -126,9 +126,9 @@ async def test_url_query_params_with_non_str_name(httpx_mock: HTTPXMock) -> None @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_url_query_params_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_url_query_params_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={"a": "1"}, is_optional=True, @@ -198,11 +198,11 @@ async def test_url_query_params_not_matching(httpx_mock: HTTPXMock) -> None: ], ) async def test_match_params_with_non_str_values_and_params_provided_as_dict( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, match_params: dict[str, Any], request_params: dict[str, Any], ) -> None: - httpx_mock.add_response(url="https://test_url", match_params=match_params) + httpx2_mock.add_response(url="https://test_url", match_params=match_params) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url", params=request_params) @@ -247,11 +247,11 @@ async def test_match_params_with_non_str_values_and_params_provided_as_dict( ], ) async def test_match_params_with_non_str_values_and_params_in_requested_url( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, match_params: dict[str, Any], url: str, ) -> None: - httpx_mock.add_response(url="https://test_url", match_params=match_params) + httpx2_mock.add_response(url="https://test_url", match_params=match_params) async with httpx2.AsyncClient() as client: response = await client.get(url) @@ -260,9 +260,9 @@ async def test_match_params_with_non_str_values_and_params_in_requested_url( @pytest.mark.asyncio async def test_url_matching_with_more_than_one_value_on_same_param( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url", params={"a": [1, 3]}) @@ -270,11 +270,11 @@ async def test_url_matching_with_more_than_one_value_on_same_param( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_not_matching_with_more_than_one_value_on_same_param_and_diff_value( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=2&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=2&a=3", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -287,11 +287,11 @@ async def test_url_not_matching_with_more_than_one_value_on_same_param_and_diff_ @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_not_matching_with_more_than_one_value_on_same_param_and_more_values( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -304,11 +304,11 @@ async def test_url_not_matching_with_more_than_one_value_on_same_param_and_more_ @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_not_matching_with_more_than_one_value_on_same_param_and_less_values( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3&a=4", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3&a=4", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -321,9 +321,9 @@ async def test_url_not_matching_with_more_than_one_value_on_same_param_and_less_ @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_url_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_url_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -336,9 +336,9 @@ async def test_url_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_url_query_string_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=2", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_url_query_string_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?a=1&a=2", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -352,8 +352,8 @@ async def test_url_query_string_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_method_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(method="get", is_reusable=True) +async def test_method_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(method="get", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -364,9 +364,9 @@ async def test_method_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_method_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(method="get", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_method_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(method="get", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -379,8 +379,8 @@ async def test_method_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_reusing_one_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_reusing_one_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"test content", is_reusable=True ) @@ -393,8 +393,8 @@ async def test_reusing_one_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_response_with_string_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", text="test content") +async def test_response_with_string_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", text="test content") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -402,8 +402,8 @@ async def test_response_with_string_body(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_response_with_html_string_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", html="
test content") +async def test_response_with_html_string_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", html="test content") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -411,8 +411,8 @@ async def test_response_with_html_string_body(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_stream_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_stream_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", stream=pytest_httpx2.IteratorStream([b"part 1", b"part 2"]), is_reusable=True, @@ -441,8 +441,8 @@ async def test_stream_response_streaming(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_content_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_content_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"part 1 and 2", is_reusable=True, @@ -469,8 +469,8 @@ async def test_content_response_streaming(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_text_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_text_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", text="part 1 and 2", is_reusable=True, @@ -497,8 +497,8 @@ async def test_text_response_streaming(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_default_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_default_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: async with client.stream(method="GET", url="https://test_url") as response: @@ -517,10 +517,10 @@ async def test_default_response_streaming(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_many_responses(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", content=b"test content 1") - httpx_mock.add_response(url="https://test_url", content=b"test content 2") - httpx_mock.add_response(url="https://test_url", content=b"test content 2") +async def test_with_many_responses(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", content=b"test content 1") + httpx2_mock.add_response(url="https://test_url", content=b"test content 2") + httpx2_mock.add_response(url="https://test_url", content=b"test content 2") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -534,9 +534,9 @@ async def test_with_many_responses(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", content=b"test content 1") - httpx_mock.add_response( +async def test_with_many_reused_responses(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", content=b"test content 1") + httpx2_mock.add_response( url="https://test_url", content=b"test content 2", is_reusable=True ) @@ -552,23 +552,23 @@ async def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_many_responses_methods(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_many_responses_methods(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6" ) @@ -593,32 +593,32 @@ async def test_with_many_responses_methods(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_many_responses_status_codes(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_many_responses_status_codes(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1", status_code=200 ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2", status_code=201, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3", status_code=202 ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4", status_code=303, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5", status_code=404, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6", @@ -652,23 +652,23 @@ async def test_with_many_responses_status_codes(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_many_responses_urls_str(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_many_responses_urls_str(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url?param1=test", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param2=test", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param3=test", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param4=test", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param5=test", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param6=test", method="HEAD", content=b"test content 6" ) @@ -705,9 +705,9 @@ async def test_with_many_responses_urls_str(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_response_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url=re.compile(".*test.*")) - httpx_mock.add_response(url="https://unmatched", content=b"test content") +async def test_response_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url=re.compile(".*test.*")) + httpx2_mock.add_response(url="https://unmatched", content=b"test content") async with httpx2.AsyncClient() as client: response = await client.get("https://unmatched") @@ -718,38 +718,38 @@ async def test_response_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_request_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") - httpx_mock.add_response(url="https://unmatched") +async def test_request_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") + httpx2_mock.add_response(url="https://unmatched") async with httpx2.AsyncClient() as client: await client.get("https://unmatched") await client.get("https://test_url", headers={"X-Test": "1"}) - request = httpx_mock.get_request(url=re.compile(".*test.*")) + request = httpx2_mock.get_request(url=re.compile(".*test.*")) assert request is not None assert request.headers["x-test"] == "1" @pytest.mark.asyncio -async def test_requests_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") - httpx_mock.add_response(url="https://tests_url") - httpx_mock.add_response(url="https://unmatched") +async def test_requests_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") + httpx2_mock.add_response(url="https://tests_url") + httpx2_mock.add_response(url="https://unmatched") async with httpx2.AsyncClient() as client: await client.get("https://tests_url", headers={"X-Test": "1"}) await client.get("https://unmatched", headers={"X-Test": "2"}) await client.get("https://test_url") - requests = httpx_mock.get_requests(url=re.compile(".*test.*")) + requests = httpx2_mock.get_requests(url=re.compile(".*test.*")) assert len(requests) == 2 assert requests[0].headers["x-test"] == "1" assert "x-test" not in requests[1].headers @pytest.mark.asyncio -async def test_callback_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: +async def test_callback_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) @@ -760,8 +760,8 @@ def custom_response2(request: httpx2.Request) -> httpx2.Response: json={"url": str(request.url)}, ) - httpx_mock.add_callback(custom_response, url=re.compile(".*test.*")) - httpx_mock.add_callback(custom_response2, url="https://unmatched") + httpx2_mock.add_callback(custom_response, url=re.compile(".*test.*")) + httpx2_mock.add_callback(custom_response2, url="https://unmatched") async with httpx2.AsyncClient() as client: response = await client.get("https://unmatched") @@ -772,7 +772,7 @@ def custom_response2(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_with_await_statement(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_with_await_statement(httpx2_mock: HTTPXMock) -> None: async def simulate_network_latency(request: httpx2.Request): await asyncio.sleep(1) return httpx2.Response( @@ -785,9 +785,9 @@ def instant_response(request: httpx2.Request) -> httpx2.Response: status_code=200, json={"url": str(request.url), "time": time.time()} ) - httpx_mock.add_callback(simulate_network_latency) - httpx_mock.add_callback(instant_response) - httpx_mock.add_response(json={"url": "not a callback"}) + httpx2_mock.add_callback(simulate_network_latency) + httpx2_mock.add_callback(instant_response) + httpx2_mock.add_response(json={"url": "not a callback"}) async with httpx2.AsyncClient() as client: responses = await asyncio.gather( @@ -809,7 +809,7 @@ def instant_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) @@ -820,8 +820,8 @@ async def custom_response2(request: httpx2.Request) -> httpx2.Response: json={"url": str(request.url)}, ) - httpx_mock.add_callback(custom_response, url=re.compile(".*test.*")) - httpx_mock.add_callback(custom_response2, url="https://unmatched") + httpx2_mock.add_callback(custom_response, url=re.compile(".*test.*")) + httpx2_mock.add_callback(custom_response2, url="https://unmatched") async with httpx2.AsyncClient() as client: response = await client.get("https://unmatched") @@ -832,33 +832,33 @@ async def custom_response2(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_with_many_responses_urls_instances(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_many_responses_urls_instances(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param1": "test"}), method="GET", content=b"test content 1", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param2": "test"}), method="POST", content=b"test content 2", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param3": "test"}), method="PUT", content=b"test content 3", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param4": "test"}), method="DELETE", content=b"test content 4", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param5": "test"}), method="PATCH", content=b"test content 5", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param6": "test"}), method="HEAD", content=b"test content 6", @@ -885,8 +885,8 @@ async def test_with_many_responses_urls_instances(httpx_mock: HTTPXMock) -> None @pytest.mark.asyncio -async def test_with_http_version_2(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_http_version_2(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", http_version="HTTP/2", content=b"test content 1" ) @@ -897,8 +897,8 @@ async def test_with_http_version_2(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_with_headers(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_with_headers(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"test content 1", headers={"X-Test": "Test value"}, @@ -913,23 +913,23 @@ async def test_with_headers(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_requests_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_requests_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6" ) @@ -941,37 +941,37 @@ async def test_requests_retrieval(httpx_mock: HTTPXMock) -> None: await client.patch("https://test_url", content=b"sent content 5") await client.delete("https://test_url", headers={"X-Test": "test header 4"}) - patch_request = httpx_mock.get_request( + patch_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="PATCH" ) assert patch_request is not None assert patch_request.read() == b"sent content 5" - head_request = httpx_mock.get_request( + head_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="HEAD" ) assert head_request is not None assert head_request.read() == b"" - put_request = httpx_mock.get_request( + put_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="PUT" ) assert put_request is not None assert put_request.read() == b"sent content 3" - get_request = httpx_mock.get_request( + get_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="GET" ) assert get_request is not None assert get_request.headers["x-test"] == "test header 1" - post_request = httpx_mock.get_request( + post_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="POST" ) assert post_request is not None assert post_request.read() == b"sent content 2" - delete_request = httpx_mock.get_request( + delete_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="DELETE" ) assert delete_request is not None @@ -979,62 +979,64 @@ async def test_requests_retrieval(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_requests_retrieval_on_same_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +async def test_requests_retrieval_on_same_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) await client.get("https://test_url", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests(url=httpx2.URL("https://test_url")) + requests = httpx2_mock.get_requests(url=httpx2.URL("https://test_url")) assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" @pytest.mark.asyncio -async def test_request_retrieval_on_same_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_request_retrieval_on_same_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) await client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - request = httpx_mock.get_request(url=httpx2.URL("https://test_url")) + request = httpx2_mock.get_request(url=httpx2.URL("https://test_url")) assert request is not None assert request.headers["x-test"] == "test header 1" @pytest.mark.asyncio -async def test_requests_retrieval_on_same_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_on_same_method(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) await client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests(method="GET") + requests = httpx2_mock.get_requests(method="GET") assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" @pytest.mark.asyncio -async def test_request_retrieval_on_same_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_request_retrieval_on_same_method(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) await client.post("https://test_url", headers={"X-TEST": "test header 2"}) - request = httpx_mock.get_request(method="GET") + request = httpx2_mock.get_request(method="GET") assert request is not None assert request.headers["x-test"] == "test header 1" @pytest.mark.asyncio -async def test_requests_retrieval_on_same_url_and_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_on_same_url_and_method( + httpx2_mock: HTTPXMock, +) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) @@ -1042,49 +1044,51 @@ async def test_requests_retrieval_on_same_url_and_method(httpx_mock: HTTPXMock) await client.post("https://test_url", headers={"X-TEST": "test header 3"}) await client.get("https://test_url2", headers={"X-TEST": "test header 4"}) - requests = httpx_mock.get_requests(url=httpx2.URL("https://test_url"), method="GET") + requests = httpx2_mock.get_requests( + url=httpx2.URL("https://test_url"), method="GET" + ) assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" @pytest.mark.asyncio -async def test_default_requests_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_default_requests_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.post("https://test_url", headers={"X-TEST": "test header 1"}) await client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests() + requests = httpx2_mock.get_requests() assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" @pytest.mark.asyncio -async def test_default_request_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +async def test_default_request_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: await client.post("https://test_url", headers={"X-TEST": "test header 1"}) - request = httpx_mock.get_request() + request = httpx2_mock.get_request() assert request is not None assert request.headers["x-test"] == "test header 1" @pytest.mark.asyncio -async def test_requests_json_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_requests_json_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", json=["list content 1", "list content 2"] ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", json={"key 1": "value 1", "key 2": "value 2"}, ) - httpx_mock.add_response(url="https://test_url", method="PUT", json="string value") + httpx2_mock.add_response(url="https://test_url", method="PUT", json="string value") async with httpx2.AsyncClient() as client: response = await client.post("https://test_url") @@ -1101,14 +1105,14 @@ async def test_requests_json_body(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_callback_raising_exception(httpx_mock: HTTPXMock) -> None: +async def test_callback_raising_exception(httpx2_mock: HTTPXMock) -> None: def raise_timeout(request: httpx2.Request) -> httpx2.Response: raise httpx2.ReadTimeout( f"Unable to read within {request.extensions['timeout']['read']}", request=request, ) - httpx_mock.add_callback(raise_timeout, url="https://test_url") + httpx2_mock.add_callback(raise_timeout, url="https://test_url") async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.ReadTimeout) as exception_info: @@ -1117,14 +1121,14 @@ def raise_timeout(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_raising_exception(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_raising_exception(httpx2_mock: HTTPXMock) -> None: async def raise_timeout(request: httpx2.Request) -> httpx2.Response: raise httpx2.ReadTimeout( f"Unable to read within {request.extensions['timeout']['read']}", request=request, ) - httpx_mock.add_callback(raise_timeout, url="https://test_url") + httpx2_mock.add_callback(raise_timeout, url="https://test_url") async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.ReadTimeout) as exception_info: @@ -1133,8 +1137,8 @@ async def raise_timeout(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_request_exception_raising(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_exception( +async def test_request_exception_raising(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_exception( httpx2.ReadTimeout("Unable to read within 5.0"), url="https://test_url" ) @@ -1162,9 +1166,9 @@ async def test_request_exception_raising(httpx_mock: HTTPXMock) -> None: ], ) async def test_non_request_exception_raising( - httpx_mock: HTTPXMock, exception_type: type, message: str + httpx2_mock: HTTPXMock, exception_type: type, message: str ) -> None: - httpx_mock.add_exception(exception_type(message), url="https://test_url") + httpx2_mock.add_exception(exception_type(message), url="https://test_url") async with httpx2.AsyncClient() as client: with pytest.raises(exception_type) as exception_info: @@ -1173,11 +1177,11 @@ async def test_non_request_exception_raising( @pytest.mark.asyncio -async def test_callback_returning_response(httpx_mock: HTTPXMock) -> None: +async def test_callback_returning_response(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) - httpx_mock.add_callback(custom_response, url="https://test_url") + httpx2_mock.add_callback(custom_response, url="https://test_url") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1187,11 +1191,11 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio @pytest.mark.parametrize("return_value", [None, "not a response"]) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_callback_not_returning_a_response( - httpx_mock: HTTPXMock, return_value: str | None + httpx2_mock: HTTPXMock, return_value: str | None ) -> None: - httpx_mock.add_callback(lambda request: return_value, url="https://test_url") + httpx2_mock.add_callback(lambda request: return_value, url="https://test_url") async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1204,14 +1208,14 @@ async def test_callback_not_returning_a_response( @pytest.mark.asyncio @pytest.mark.parametrize("return_value", [None, "not a response"]) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_async_callback_not_returning_a_response( - httpx_mock: HTTPXMock, return_value: str | None + httpx2_mock: HTTPXMock, return_value: str | None ) -> None: async def invalid_response(request: httpx2.Request) -> httpx2.Response: return return_value - httpx_mock.add_callback(invalid_response, url="https://test_url") + httpx2_mock.add_callback(invalid_response, url="https://test_url") async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1223,11 +1227,11 @@ async def invalid_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_returning_response(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_returning_response(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) - httpx_mock.add_callback(custom_response, url="https://test_url") + httpx2_mock.add_callback(custom_response, url="https://test_url") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1236,11 +1240,11 @@ async def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_callback_executed_twice(httpx_mock: HTTPXMock) -> None: +async def test_callback_executed_twice(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_callback(custom_response, is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1253,11 +1257,11 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_executed_twice(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_executed_twice(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_callback(custom_response, is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1270,12 +1274,12 @@ async def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_callback_registered_after_response(httpx_mock: HTTPXMock) -> None: +async def test_callback_registered_after_response(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content2"]) - httpx_mock.add_response(json=["content1"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_response(json=["content1"]) + httpx2_mock.add_callback(custom_response, is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1293,12 +1297,12 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_registered_after_response(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_registered_after_response(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content2"]) - httpx_mock.add_response(json=["content1"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_response(json=["content1"]) + httpx2_mock.add_callback(custom_response, is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1316,12 +1320,12 @@ async def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_response_registered_after_callback(httpx_mock: HTTPXMock) -> None: +async def test_response_registered_after_callback(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content1"]) - httpx_mock.add_callback(custom_response) - httpx_mock.add_response(json=["content2"], is_reusable=True) + httpx2_mock.add_callback(custom_response) + httpx2_mock.add_response(json=["content2"], is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1339,12 +1343,12 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_response_registered_after_async_callback(httpx_mock: HTTPXMock) -> None: +async def test_response_registered_after_async_callback(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content1"]) - httpx_mock.add_callback(custom_response) - httpx_mock.add_response(json=["content2"], is_reusable=True) + httpx2_mock.add_callback(custom_response) + httpx2_mock.add_response(json=["content2"], is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1362,11 +1366,11 @@ async def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_callback_matching_method(httpx_mock: HTTPXMock) -> None: +async def test_callback_matching_method(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, method="GET", is_reusable=True) + httpx2_mock.add_callback(custom_response, method="GET", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1379,11 +1383,11 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_async_callback_matching_method(httpx_mock: HTTPXMock) -> None: +async def test_async_callback_matching_method(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, method="GET", is_reusable=True) + httpx2_mock.add_callback(custom_response, method="GET", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -1405,14 +1409,14 @@ def test_request_retrieval_with_more_than_one(testdir: Testdir) -> None: @pytest.mark.asyncio - async def test_request_retrieval_with_more_than_one(httpx_mock): - httpx_mock.add_response(is_reusable=True) + async def test_request_retrieval_with_more_than_one(httpx2_mock): + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", headers={"X-TEST": "test header 1"}) await client.get("https://test_url", headers={"X-TEST": "test header 2"}) - httpx_mock.get_request(url=httpx2.URL("https://test_url")) + httpx2_mock.get_request(url=httpx2.URL("https://test_url")) """) result = testdir.runpytest() result.assert_outcomes(failed=1) @@ -1424,8 +1428,8 @@ async def test_request_retrieval_with_more_than_one(httpx_mock): @pytest.mark.asyncio -async def test_headers_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_headers_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={"User-Agent": f"python-httpx2/{httpx2.__version__}"} ) @@ -1435,8 +1439,8 @@ async def test_headers_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_headers={"my-custom-header": "value1, value2"}) +async def test_multi_value_headers_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_headers={"my-custom-header": "value1, value2"}) async with httpx2.AsyncClient() as client: response = await client.get( @@ -1447,11 +1451,11 @@ async def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_multi_value_headers_not_matching_single_value_issued( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( match_headers={"my-custom-header": "value1"}, is_optional=True ) @@ -1472,11 +1476,11 @@ async def test_multi_value_headers_not_matching_single_value_issued( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_multi_value_headers_not_matching_multi_value_issued( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( match_headers={"my-custom-header": "value1, value2"}, is_optional=True ) @@ -1497,9 +1501,9 @@ async def test_multi_value_headers_not_matching_multi_value_issued( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_matching_respect_case(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={"user-agent": f"python-httpx2/{httpx2.__version__}"}, is_optional=True, ) @@ -1515,9 +1519,9 @@ async def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", "Host": "test_url2", @@ -1537,11 +1541,11 @@ async def test_headers_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_not_matching_upper_case_headers_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( method="GET", url="https://test_url?q=b", match_headers={"MyHeader": "Something"}, @@ -1558,8 +1562,8 @@ async def test_url_not_matching_upper_case_headers_matching( @pytest.mark.asyncio -async def test_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_content=b"This is the body") +async def test_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_content=b"This is the body") async with httpx2.AsyncClient() as client: response = await client.post("https://test_url", content=b"This is the body") @@ -1567,8 +1571,8 @@ async def test_content_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_proxy_matching_with_authentication(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") +async def test_proxy_matching_with_authentication(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") async with httpx2.AsyncClient(proxy="http://user:pwd@my_other_proxy") as client: response = await client.get("https://test_url") @@ -1576,8 +1580,8 @@ async def test_proxy_matching_with_authentication(httpx_mock: HTTPXMock) -> None @pytest.mark.asyncio -async def test_proxy_matching_with_custom_proxy_headers(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy/") +async def test_proxy_matching_with_custom_proxy_headers(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy/") async with httpx2.AsyncClient( proxy=httpx2.Proxy("http://my_test_proxy", headers={"X-Something": "value"}) @@ -1588,9 +1592,9 @@ async def test_proxy_matching_with_custom_proxy_headers(httpx_mock: HTTPXMock) - @pytest.mark.asyncio async def test_proxy_matching_with_authentication_and_custom_proxy_headers( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") + httpx2_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") async with httpx2.AsyncClient( proxy=httpx2.Proxy( @@ -1602,9 +1606,9 @@ async def test_proxy_matching_with_authentication_and_custom_proxy_headers( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_proxy_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_proxy_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) async with httpx2.AsyncClient(proxy="http://my_test_proxy") as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1617,9 +1621,9 @@ async def test_proxy_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_proxy_not_existing(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_proxy_not_existing(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1632,32 +1636,32 @@ async def test_proxy_not_existing(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_requests_retrieval_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.post("https://test_url", content=b"This is the body") await client.post("https://test_url2", content=b"This is the body") await client.post("https://test_url2", content=b"This is the body2") - assert len(httpx_mock.get_requests(match_content=b"This is the body")) == 2 + assert len(httpx2_mock.get_requests(match_content=b"This is the body")) == 2 @pytest.mark.asyncio -async def test_requests_retrieval_json_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_json_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.post("https://test_url", json=["my_str"]) await client.post("https://test_url2", json=["my_str"]) await client.post("https://test_url2", json=["my_str2"]) - assert len(httpx_mock.get_requests(match_json=["my_str"])) == 2 + assert len(httpx2_mock.get_requests(match_json=["my_str"])) == 2 @pytest.mark.asyncio -async def test_requests_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_proxy_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient( mounts={ @@ -1672,13 +1676,13 @@ async def test_requests_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: await client.get("http://test_url2") assert ( - len(httpx_mock.get_requests(proxy_url="http://user:pwd@my_other_proxy/")) == 2 + len(httpx2_mock.get_requests(proxy_url="http://user:pwd@my_other_proxy/")) == 2 ) @pytest.mark.asyncio -async def test_request_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_request_retrieval_proxy_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient( mounts={ @@ -1692,14 +1696,14 @@ async def test_request_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: await client.get("https://test_url2") await client.get("http://test_url2") - assert httpx_mock.get_request(proxy_url="http://my_test_proxy/") + assert httpx2_mock.get_request(proxy_url="http://my_test_proxy/") @pytest.mark.asyncio async def test_requests_retrieval_files_and_data_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(is_reusable=True) + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.put( @@ -1720,7 +1724,7 @@ async def test_requests_retrieval_files_and_data_matching( assert ( len( - httpx_mock.get_requests( + httpx2_mock.get_requests( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, ) @@ -1730,8 +1734,10 @@ async def test_requests_retrieval_files_and_data_matching( @pytest.mark.asyncio -async def test_request_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_request_retrieval_files_and_data_matching( + httpx2_mock: HTTPXMock, +) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.put( @@ -1742,15 +1748,15 @@ async def test_request_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) await client.get("https://test_url2") await client.get("http://test_url2") - assert httpx_mock.get_request( + assert httpx2_mock.get_request( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, ) @pytest.mark.asyncio -async def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_requests_retrieval_extensions_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url") @@ -1758,7 +1764,7 @@ async def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> await client.get("https://test_url2", timeout=10) assert ( len( - httpx_mock.get_requests( + httpx2_mock.get_requests( match_extensions={ "timeout": {"connect": 10, "read": 10, "write": 10, "pool": 10} } @@ -1769,23 +1775,23 @@ async def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> @pytest.mark.asyncio -async def test_request_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +async def test_request_retrieval_extensions_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) async with httpx2.AsyncClient() as client: await client.get("https://test_url", timeout=httpx2.Timeout(5, read=10)) await client.get("https://test_url2", timeout=10) await client.get("http://test_url2", timeout=10) - assert httpx_mock.get_request( + assert httpx2_mock.get_request( match_extensions={"timeout": {"connect": 5, "read": 10, "write": 5, "pool": 5}} ) @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_content_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_content=b"This is the body", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_content_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_content=b"This is the body", is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1798,8 +1804,8 @@ async def test_content_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_json_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_json={"a": 1, "b": 2}) +async def test_json_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_json={"a": 1, "b": 2}) async with httpx2.AsyncClient() as client: response = await client.post("https://test_url", json={"b": 2, "a": 1}) @@ -1807,8 +1813,8 @@ async def test_json_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_json_partial_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_json={"a": 1, "b": ANY}) +async def test_json_partial_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_json={"a": 1, "b": ANY}) async with httpx2.AsyncClient() as client: response = await client.post("https://test_url", json={"b": 2, "a": 1}) @@ -1816,9 +1822,9 @@ async def test_json_partial_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_json_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_json={"a": 1, "b": 2}, is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_json_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_json={"a": 1, "b": 2}, is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1831,9 +1837,9 @@ async def test_json_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_and_json_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_and_json_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_json={"a": 1, "b": 2}, match_headers={"foo": "bar"}, is_optional=True, @@ -1850,9 +1856,9 @@ async def test_headers_and_json_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_match_json_invalid_json(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_json={"a": 1, "b": 2}, is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_match_json_invalid_json(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_json={"a": 1, "b": 2}, is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1865,8 +1871,8 @@ async def test_match_json_invalid_json(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_headers_and_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_headers_and_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={"User-Agent": f"python-httpx2/{httpx2.__version__}"}, match_content=b"This is the body", ) @@ -1877,9 +1883,11 @@ async def test_headers_and_content_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_not_matching_and_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_not_matching_and_content_matching( + httpx2_mock: HTTPXMock, +) -> None: + httpx2_mock.add_response( match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", "Host": "test_url2", @@ -1899,9 +1907,11 @@ async def test_headers_not_matching_and_content_matching(httpx_mock: HTTPXMock) @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_matching_and_content_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_matching_and_content_not_matching( + httpx2_mock: HTTPXMock, +) -> None: + httpx2_mock.add_response( match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", "Host": "test_url", @@ -1921,9 +1931,9 @@ async def test_headers_matching_and_content_not_matching(httpx_mock: HTTPXMock) @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_headers_and_content_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_headers_and_content_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", "Host": "test_url2", @@ -1943,8 +1953,8 @@ async def test_headers_and_content_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_and_headers_and_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_url_and_headers_and_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_headers={"User-Agent": f"python-httpx2/{httpx2.__version__}"}, match_content=b"This is the body", @@ -1956,11 +1966,11 @@ async def test_url_and_headers_and_content_matching(httpx_mock: HTTPXMock) -> No @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_headers_not_matching_and_url_and_content_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -1981,11 +1991,11 @@ async def test_headers_not_matching_and_url_and_content_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_and_headers_not_matching_and_content_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -2006,11 +2016,11 @@ async def test_url_and_headers_not_matching_and_content_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_and_headers_matching_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -2031,11 +2041,11 @@ async def test_url_and_headers_matching_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_headers_matching_and_url_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -2056,11 +2066,11 @@ async def test_headers_matching_and_url_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_matching_and_headers_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -2081,9 +2091,9 @@ async def test_url_matching_and_headers_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_url_and_headers_and_content_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_url_and_headers_and_content_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url2", match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", @@ -2105,9 +2115,9 @@ async def test_url_and_headers_and_content_not_matching(httpx_mock: HTTPXMock) - @pytest.mark.asyncio async def test_method_and_url_and_headers_and_content_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", match_headers={"User-Agent": f"python-httpx2/{httpx2.__version__}"}, @@ -2120,11 +2130,11 @@ async def test_method_and_url_and_headers_and_content_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_headers_not_matching_and_method_and_url_and_content_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", match_headers={ @@ -2146,11 +2156,11 @@ async def test_headers_not_matching_and_method_and_url_and_content_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_url_and_headers_not_matching_and_method_and_content_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", method="POST", match_headers={ @@ -2172,11 +2182,11 @@ async def test_url_and_headers_not_matching_and_method_and_content_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_method_and_url_and_headers_matching_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", match_headers={ @@ -2198,11 +2208,11 @@ async def test_method_and_url_and_headers_matching_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_method_and_headers_matching_and_url_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", method="POST", match_headers={ @@ -2224,11 +2234,11 @@ async def test_method_and_headers_matching_and_url_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_method_and_url_matching_and_headers_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", match_headers={ @@ -2250,11 +2260,11 @@ async def test_method_and_url_matching_and_headers_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_method_matching_and_url_and_headers_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", method="POST", match_headers={ @@ -2276,11 +2286,11 @@ async def test_method_matching_and_url_and_headers_and_content_not_matching( @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_method_and_url_and_headers_and_content_not_matching( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url2", method="PUT", match_headers={ @@ -2302,8 +2312,8 @@ async def test_method_and_url_and_headers_and_content_not_matching( @pytest.mark.asyncio -async def test_header_as_str_tuple_list(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_header_as_str_tuple_list(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( headers=[("set-cookie", "key=value"), ("set-cookie", "key2=value2")] ) @@ -2314,8 +2324,8 @@ async def test_header_as_str_tuple_list(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_header_as_bytes_tuple_list(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_header_as_bytes_tuple_list(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( headers=[(b"set-cookie", b"key=value"), (b"set-cookie", b"key2=value2")] ) @@ -2326,8 +2336,8 @@ async def test_header_as_bytes_tuple_list(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_header_as_bytes_dict(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(headers={b"set-cookie": b"key=value"}) +async def test_header_as_bytes_dict(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(headers={b"set-cookie": b"key=value"}) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2336,8 +2346,8 @@ async def test_header_as_bytes_dict(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_header_as_httpx_headers(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(headers=httpx2.Headers({"set-cookie": "key=value"})) +async def test_header_as_httpx_headers(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(headers=httpx2.Headers({"set-cookie": "key=value"})) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2346,8 +2356,8 @@ async def test_header_as_httpx_headers(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_elapsed_when_add_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +async def test_elapsed_when_add_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2355,8 +2365,8 @@ async def test_elapsed_when_add_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_elapsed_when_add_callback(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_callback( +async def test_elapsed_when_add_callback(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_callback( callback=lambda req: httpx2.Response(status_code=200, json={"foo": "bar"}) ) @@ -2366,11 +2376,11 @@ async def test_elapsed_when_add_callback(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_elapsed_when_add_async_callback(httpx_mock: HTTPXMock) -> None: +async def test_elapsed_when_add_async_callback(httpx2_mock: HTTPXMock) -> None: async def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"foo": "bar"}) - httpx_mock.add_callback(custom_response) + httpx2_mock.add_callback(custom_response) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2378,8 +2388,8 @@ async def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.asyncio -async def test_non_ascii_url_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?query_type=数据") +async def test_non_ascii_url_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?query_type=数据") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url?query_type=数据") @@ -2387,8 +2397,8 @@ async def test_non_ascii_url_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_url_encoded_matching_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?a=%E6%95%B0%E6%8D%AE") +async def test_url_encoded_matching_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?a=%E6%95%B0%E6%8D%AE") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url?a=数据") @@ -2396,24 +2406,24 @@ async def test_url_encoded_matching_response(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_reset_is_removing_requests(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +async def test_reset_is_removing_requests(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() async with httpx2.AsyncClient() as client: await client.get("https://test_url") - assert len(httpx_mock.get_requests()) == 1 + assert len(httpx2_mock.get_requests()) == 1 - httpx_mock.reset() - assert len(httpx_mock.get_requests()) == 0 + httpx2_mock.reset() + assert len(httpx2_mock.get_requests()) == 0 @pytest.mark.asyncio -async def test_mutating_json(httpx_mock: HTTPXMock) -> None: +async def test_mutating_json(httpx2_mock: HTTPXMock) -> None: mutating_json = {"content": "request 1"} - httpx_mock.add_response(json=mutating_json) + httpx2_mock.add_response(json=mutating_json) mutating_json["content"] = "request 2" - httpx_mock.add_response(json=mutating_json) + httpx2_mock.add_response(json=mutating_json) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2425,9 +2435,9 @@ async def test_mutating_json(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio async def test_streams_are_not_cascading_resulting_in_maximum_recursion( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(json={"abc": "def"}, is_reusable=True) + httpx2_mock.add_response(json={"abc": "def"}, is_reusable=True) async with httpx2.AsyncClient() as client: tasks = [client.get("https://test_url") for _ in range(950)] await asyncio.gather(*tasks) @@ -2435,7 +2445,7 @@ async def test_streams_are_not_cascading_resulting_in_maximum_recursion( @pytest.mark.asyncio -async def test_custom_transport(httpx_mock: HTTPXMock) -> None: +async def test_custom_transport(httpx2_mock: HTTPXMock) -> None: class CustomTransport(httpx2.AsyncHTTPTransport): def __init__(self, prefix: str, *args, **kwargs): super().__init__(*args, **kwargs) @@ -2449,7 +2459,7 @@ async def handle_async_request( httpx_response.headers["x-prefix"] = self.prefix return httpx_response - httpx_mock.add_response() + httpx2_mock.add_response() async with httpx2.AsyncClient(transport=CustomTransport(prefix="test")) as client: response = await client.post("https://test_url", content=b"This is the body") @@ -2459,10 +2469,10 @@ async def handle_async_request( @pytest.mark.asyncio async def test_response_selection_content_matching_with_async_iterable( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(match_content=b"full content 1", content=b"matched 1") - httpx_mock.add_response(match_content=b"full content 2", content=b"matched 2") + httpx2_mock.add_response(match_content=b"full content 1", content=b"matched 1") + httpx2_mock.add_response(match_content=b"full content 2", content=b"matched 2") async def stream_content_1() -> AsyncIterable[bytes]: yield b"full" @@ -2485,10 +2495,10 @@ async def stream_content_2() -> AsyncIterable[bytes]: @pytest.mark.asyncio async def test_request_selection_content_matching_with_async_iterable( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(match_content=b"full content 1") - httpx_mock.add_response(match_content=b"full content 2") + httpx2_mock.add_response(match_content=b"full content 1") + httpx2_mock.add_response(match_content=b"full content 2") async def stream_content_1() -> AsyncIterable[bytes]: yield b"full" @@ -2506,18 +2516,18 @@ async def stream_content_2() -> AsyncIterable[bytes]: await client.put("https://test_url_2", content=stream_content_2()) await client.put("https://test_url_1", content=stream_content_1()) - request1 = httpx_mock.get_request(match_content=b"full content 1") + request1 = httpx2_mock.get_request(match_content=b"full content 1") assert request1 is not None assert request1.url == "https://test_url_1" - request2 = httpx_mock.get_request(match_content=b"full content 2") + request2 = httpx2_mock.get_request(match_content=b"full content 2") assert request2 is not None assert request2.url == "https://test_url_2" @pytest.mark.asyncio -async def test_files_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_files={"name": ("file_name", b"File content")}) +async def test_files_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_files={"name": ("file_name", b"File content")}) async with httpx2.AsyncClient() as client: response = await client.put( @@ -2527,8 +2537,8 @@ async def test_files_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_files_and_data_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_files_and_data_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, ) @@ -2543,8 +2553,8 @@ async def test_files_and_data_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_files_not_matching_name(httpx_mock: HTTPXMock, monkeypatch) -> None: +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_files_not_matching_name(httpx2_mock: HTTPXMock, monkeypatch) -> None: # Ensure generated boundary will be fbe495efe4cd41b941ca13e254d6b018 monkeypatch.setattr( os, @@ -2552,7 +2562,7 @@ async def test_files_not_matching_name(httpx_mock: HTTPXMock, monkeypatch) -> No lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18", ) - httpx_mock.add_response( + httpx2_mock.add_response( match_files={"name2": ("file_name", b"File content")}, is_optional=True ) @@ -2569,8 +2579,10 @@ async def test_files_not_matching_name(httpx_mock: HTTPXMock, monkeypatch) -> No @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_files_not_matching_file_name(httpx_mock: HTTPXMock, monkeypatch) -> None: +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_files_not_matching_file_name( + httpx2_mock: HTTPXMock, monkeypatch +) -> None: # Ensure generated boundary will be fbe495efe4cd41b941ca13e254d6b018 monkeypatch.setattr( os, @@ -2578,7 +2590,7 @@ async def test_files_not_matching_file_name(httpx_mock: HTTPXMock, monkeypatch) lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18", ) - httpx_mock.add_response( + httpx2_mock.add_response( match_files={"name": ("file_name2", b"File content")}, is_optional=True ) @@ -2595,8 +2607,8 @@ async def test_files_not_matching_file_name(httpx_mock: HTTPXMock, monkeypatch) @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_files_not_matching_content(httpx_mock: HTTPXMock, monkeypatch) -> None: +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_files_not_matching_content(httpx2_mock: HTTPXMock, monkeypatch) -> None: # Ensure generated boundary will be fbe495efe4cd41b941ca13e254d6b018 monkeypatch.setattr( os, @@ -2604,7 +2616,7 @@ async def test_files_not_matching_content(httpx_mock: HTTPXMock, monkeypatch) -> lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18", ) - httpx_mock.add_response( + httpx2_mock.add_response( match_files={"name": ("file_name", b"File content2")}, is_optional=True ) @@ -2621,9 +2633,9 @@ async def test_files_not_matching_content(httpx_mock: HTTPXMock, monkeypatch) -> @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) async def test_files_matching_but_data_not_matching( - httpx_mock: HTTPXMock, monkeypatch + httpx2_mock: HTTPXMock, monkeypatch ) -> None: # Ensure generated boundary will be fbe495efe4cd41b941ca13e254d6b018 monkeypatch.setattr( @@ -2632,7 +2644,7 @@ async def test_files_matching_but_data_not_matching( lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18", ) - httpx_mock.add_response( + httpx2_mock.add_response( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, is_optional=True, @@ -2651,8 +2663,8 @@ async def test_files_matching_but_data_not_matching( @pytest.mark.asyncio -async def test_timeout_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +async def test_timeout_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_extensions={"timeout": {"connect": 5, "read": 5, "write": 10, "pool": 5}} ) @@ -2664,9 +2676,9 @@ async def test_timeout_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_timeout_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_timeout_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_extensions={"timeout": {"connect": 5, "read": 5, "write": 10, "pool": 5}}, is_optional=True, ) @@ -2682,8 +2694,8 @@ async def test_timeout_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_extensions_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_extensions={"test": "value"}) +async def test_extensions_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_extensions={"test": "value"}) async with httpx2.AsyncClient() as client: response = await client.put( @@ -2693,9 +2705,9 @@ async def test_extensions_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -async def test_extensions_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_extensions={"test": "value"}, is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +async def test_extensions_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_extensions={"test": "value"}, is_optional=True) async with httpx2.AsyncClient() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -2708,10 +2720,10 @@ async def test_extensions_not_matching(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_optional_response_not_matched(httpx_mock: HTTPXMock) -> None: +async def test_optional_response_not_matched(httpx2_mock: HTTPXMock) -> None: # This response is optional and the fact that it was never requested should not trigger anything - httpx_mock.add_response(url="https://test_url", is_optional=True) - httpx_mock.add_response(url="https://test_url2") + httpx2_mock.add_response(url="https://test_url", is_optional=True) + httpx2_mock.add_response(url="https://test_url2") async with httpx2.AsyncClient() as client: response = await client.get("https://test_url2") @@ -2719,10 +2731,10 @@ async def test_optional_response_not_matched(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_optional_response_matched(httpx_mock: HTTPXMock) -> None: +async def test_optional_response_matched(httpx2_mock: HTTPXMock) -> None: # This response is optional and the fact that it was never requested should not trigger anything - httpx_mock.add_response(url="https://test_url", is_optional=True) - httpx_mock.add_response(url="https://test_url2") + httpx2_mock.add_response(url="https://test_url", is_optional=True) + httpx2_mock.add_response(url="https://test_url2") async with httpx2.AsyncClient() as client: response1 = await client.get("https://test_url") @@ -2732,12 +2744,12 @@ async def test_optional_response_matched(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -@pytest.mark.httpx_mock(assert_all_responses_were_requested=False) -async def test_mandatory_response_matched(httpx_mock: HTTPXMock) -> None: +@pytest.mark.httpx2_mock(assert_all_responses_were_requested=False) +async def test_mandatory_response_matched(httpx2_mock: HTTPXMock) -> None: # This response is optional and the fact that it was never requested should not trigger anything - httpx_mock.add_response(url="https://test_url") + httpx2_mock.add_response(url="https://test_url") # This response MUST be requested (overrides global settings via marker) - httpx_mock.add_response(url="https://test_url2", is_optional=False) + httpx2_mock.add_response(url="https://test_url2", is_optional=False) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url2") @@ -2745,8 +2757,8 @@ async def test_mandatory_response_matched(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_multi_response_matched_once(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +async def test_multi_response_matched_once(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) async with httpx2.AsyncClient() as client: response = await client.get("https://test_url") @@ -2754,8 +2766,8 @@ async def test_multi_response_matched_once(httpx_mock: HTTPXMock) -> None: @pytest.mark.asyncio -async def test_multi_response_matched_twice(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +async def test_multi_response_matched_twice(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) async with httpx2.AsyncClient() as client: response1 = await client.get("https://test_url") diff --git a/tests/test_httpx_sync.py b/tests/test_httpx_sync.py index fbde5e3..22ad1a9 100644 --- a/tests/test_httpx_sync.py +++ b/tests/test_httpx_sync.py @@ -12,8 +12,8 @@ from pytest_httpx2 import HTTPXMock -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_without_response(httpx_mock: HTTPXMock) -> None: +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_without_response(httpx2_mock: HTTPXMock) -> None: with pytest.raises(Exception) as exception_info: with httpx2.Client() as client: client.get("https://test_url") @@ -23,8 +23,8 @@ def test_without_response(httpx_mock: HTTPXMock) -> None: ) -def test_default_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +def test_default_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() with httpx2.Client() as client: response = client.get("https://test_url") @@ -34,16 +34,16 @@ def test_default_response(httpx_mock: HTTPXMock) -> None: assert response.http_version == "HTTP/1.1" -def test_url_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") +def test_url_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") with httpx2.Client() as client: response = client.get("https://test_url") assert response.content == b"" -def test_url_matching_reusing_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +def test_url_matching_reusing_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -53,8 +53,8 @@ def test_url_matching_reusing_response(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_url_query_string_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?a=1&b=2", is_reusable=True) +def test_url_query_string_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?a=1&b=2", is_reusable=True) with httpx2.Client() as client: response = client.post("https://test_url?a=1&b=2") @@ -65,8 +65,8 @@ def test_url_query_string_matching(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_url_query_params_partial_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_url_query_params_partial_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={"a": ["1", "3"], "b": ANY, "c": "4", "d": ["5", ANY], "e": [ANY]}, is_reusable=True, @@ -81,24 +81,24 @@ def test_url_query_params_partial_matching(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_url_as_pattern_ignoring_query_parameters(httpx_mock: HTTPXMock): - httpx_mock.add_response(url=re.compile("https://test_url/something.*")) +def test_url_as_pattern_ignoring_query_parameters(httpx2_mock: HTTPXMock): + httpx2_mock.add_response(url=re.compile("https://test_url/something.*")) with httpx2.Client() as client: response = client.get("https://test_url/something?a=1&b=2") assert response.content == b"" -def test_url_query_params_with_single_value_list(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", match_params={"a": ["1"]}) +def test_url_query_params_with_single_value_list(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", match_params={"a": ["1"]}) with httpx2.Client() as client: response = client.post("https://test_url?a=1") assert response.content == b"" -def test_url_query_params_with_non_str_name(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_url_query_params_with_non_str_name(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={1: "1"}, ) @@ -108,18 +108,18 @@ def test_url_query_params_with_non_str_name(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_match_params_without_url(httpx_mock: HTTPXMock) -> None: +def test_match_params_without_url(httpx2_mock: HTTPXMock) -> None: with pytest.raises(ValueError) as exception_info: - httpx_mock.add_response(match_params={"a": "1"}) + httpx2_mock.add_response(match_params={"a": "1"}) assert ( str(exception_info.value) == "URL must be provided when match_params is used." ) -def test_query_params_in_both_url_and_match_params(httpx_mock: HTTPXMock) -> None: +def test_query_params_in_both_url_and_match_params(httpx2_mock: HTTPXMock) -> None: with pytest.raises(ValueError) as exception_info: - httpx_mock.add_response(url="https://test_url?a=1", match_params={"a": "1"}) + httpx2_mock.add_response(url="https://test_url?a=1", match_params={"a": "1"}) assert ( str(exception_info.value) @@ -127,9 +127,9 @@ def test_query_params_in_both_url_and_match_params(httpx_mock: HTTPXMock) -> Non ) -def test_regex_url_and_match_params(httpx_mock: HTTPXMock) -> None: +def test_regex_url_and_match_params(httpx2_mock: HTTPXMock) -> None: with pytest.raises(ValueError) as exception_info: - httpx_mock.add_response(url=re.compile(".*test.*"), match_params={"a": "1"}) + httpx2_mock.add_response(url=re.compile(".*test.*"), match_params={"a": "1"}) assert ( str(exception_info.value) @@ -137,9 +137,9 @@ def test_regex_url_and_match_params(httpx_mock: HTTPXMock) -> None: ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_url_query_params_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_url_query_params_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", match_params={"a": "1"}, is_optional=True, @@ -208,11 +208,11 @@ def test_url_query_params_not_matching(httpx_mock: HTTPXMock) -> None: ], ) def test_match_params_with_non_str_values_and_params_provided_as_dict( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, match_params: dict[str, Any], request_params: dict[str, Any], ) -> None: - httpx_mock.add_response(url="https://test_url", match_params=match_params) + httpx2_mock.add_response(url="https://test_url", match_params=match_params) with httpx2.Client() as client: response = client.get("https://test_url", params=request_params) @@ -256,11 +256,11 @@ def test_match_params_with_non_str_values_and_params_provided_as_dict( ], ) def test_match_params_with_non_str_values_and_params_in_requested_url( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, match_params: dict[str, Any], url: str, ) -> None: - httpx_mock.add_response(url="https://test_url", match_params=match_params) + httpx2_mock.add_response(url="https://test_url", match_params=match_params) with httpx2.Client() as client: response = client.get(url) @@ -268,20 +268,20 @@ def test_match_params_with_non_str_values_and_params_in_requested_url( def test_url_matching_with_more_than_one_value_on_same_param( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) with httpx2.Client() as client: response = client.get("https://test_url", params={"a": [1, 3]}) assert response.content == b"" -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_url_not_matching_with_more_than_one_value_on_same_param_and_diff_value( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=2&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=2&a=3", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -293,11 +293,11 @@ def test_url_not_matching_with_more_than_one_value_on_same_param_and_diff_value( ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_url_not_matching_with_more_than_one_value_on_same_param_and_more_values( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -309,11 +309,11 @@ def test_url_not_matching_with_more_than_one_value_on_same_param_and_more_values ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_url_not_matching_with_more_than_one_value_on_same_param_and_less_values( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=3&a=4", is_optional=True) + httpx2_mock.add_response(url="https://test_url?a=1&a=3&a=4", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -325,9 +325,9 @@ def test_url_not_matching_with_more_than_one_value_on_same_param_and_less_values ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_url_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_url_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -339,9 +339,9 @@ def test_url_not_matching(httpx_mock: HTTPXMock) -> None: ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_url_query_string_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url?a=1&a=2", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_url_query_string_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url?a=1&a=2", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -354,8 +354,8 @@ def test_url_query_string_not_matching(httpx_mock: HTTPXMock) -> None: ) -def test_method_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(method="get", is_reusable=True) +def test_method_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(method="get", is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -365,9 +365,9 @@ def test_method_matching(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_method_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(method="get", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_method_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(method="get", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -379,8 +379,8 @@ def test_method_not_matching(httpx_mock: HTTPXMock) -> None: ) -def test_reusing_one_response(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_reusing_one_response(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"test content", is_reusable=True ) @@ -392,25 +392,25 @@ def test_reusing_one_response(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content" -def test_response_with_string_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", text="test content") +def test_response_with_string_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", text="test content") with httpx2.Client() as client: response = client.get("https://test_url") assert response.content == b"test content" -def test_response_with_html_string_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", html="test content") +def test_response_with_html_string_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", html="test content") with httpx2.Client() as client: response = client.get("https://test_url") assert response.text == "test content" -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_url_not_matching_upper_case_headers_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_url_not_matching_upper_case_headers_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( method="GET", url="https://test_url?q=b", match_headers={"MyHeader": "Something"}, @@ -426,8 +426,8 @@ def test_url_not_matching_upper_case_headers_matching(httpx_mock: HTTPXMock) -> ) -def test_stream_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_stream_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", stream=pytest_httpx2.IteratorStream([b"part 1", b"part 2"]), is_reusable=True, @@ -448,8 +448,8 @@ def test_stream_response_streaming(httpx_mock: HTTPXMock) -> None: list(response.iter_raw()) -def test_content_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_content_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"part 1 and 2", is_reusable=True, @@ -470,8 +470,8 @@ def test_content_response_streaming(httpx_mock: HTTPXMock) -> None: list(response.iter_raw()) -def test_text_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_text_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", text="part 1 and 2", is_reusable=True, @@ -492,8 +492,8 @@ def test_text_response_streaming(httpx_mock: HTTPXMock) -> None: list(response.iter_raw()) -def test_default_response_streaming(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_default_response_streaming(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: with client.stream(method="GET", url="https://test_url") as response: @@ -510,10 +510,10 @@ def test_default_response_streaming(httpx_mock: HTTPXMock) -> None: list(response.iter_raw()) -def test_with_many_responses(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", content=b"test content 1") - httpx_mock.add_response(url="https://test_url", content=b"test content 2") - httpx_mock.add_response(url="https://test_url", content=b"test content 2") +def test_with_many_responses(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", content=b"test content 1") + httpx2_mock.add_response(url="https://test_url", content=b"test content 2") + httpx2_mock.add_response(url="https://test_url", content=b"test content 2") with httpx2.Client() as client: response = client.get("https://test_url") @@ -526,9 +526,9 @@ def test_with_many_responses(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content 2" -def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", content=b"test content 1") - httpx_mock.add_response( +def test_with_many_reused_responses(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", content=b"test content 1") + httpx2_mock.add_response( url="https://test_url", content=b"test content 2", is_reusable=True ) @@ -543,23 +543,23 @@ def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content 2" -def test_with_many_responses_methods(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_many_responses_methods(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6" ) @@ -583,32 +583,32 @@ def test_with_many_responses_methods(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content 4" -def test_with_many_responses_status_codes(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_many_responses_status_codes(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1", status_code=200 ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2", status_code=201, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3", status_code=202 ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4", status_code=303, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5", status_code=404, ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6", @@ -641,23 +641,23 @@ def test_with_many_responses_status_codes(httpx_mock: HTTPXMock) -> None: assert response.status_code == 303 -def test_with_many_responses_urls_str(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_many_responses_urls_str(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url?param1=test", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param2=test", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param3=test", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param4=test", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param5=test", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url?param6=test", method="HEAD", content=b"test content 6" ) @@ -689,9 +689,9 @@ def test_with_many_responses_urls_str(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content 4" -def test_response_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url=re.compile(".*test.*")) - httpx_mock.add_response(url="https://unmatched", content=b"test content") +def test_response_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url=re.compile(".*test.*")) + httpx2_mock.add_response(url="https://unmatched", content=b"test content") with httpx2.Client() as client: response = client.get("https://unmatched") @@ -701,36 +701,36 @@ def test_response_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_request_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") - httpx_mock.add_response(url="https://unmatched") +def test_request_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") + httpx2_mock.add_response(url="https://unmatched") with httpx2.Client() as client: client.get("https://unmatched") client.get("https://test_url", headers={"X-Test": "1"}) - request = httpx_mock.get_request(url=re.compile(".*test.*")) + request = httpx2_mock.get_request(url=re.compile(".*test.*")) assert request is not None assert request.headers["x-test"] == "1" -def test_requests_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url") - httpx_mock.add_response(url="https://tests_url") - httpx_mock.add_response(url="https://unmatched") +def test_requests_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url") + httpx2_mock.add_response(url="https://tests_url") + httpx2_mock.add_response(url="https://unmatched") with httpx2.Client() as client: client.get("https://tests_url", headers={"X-Test": "1"}) client.get("https://unmatched", headers={"X-Test": "2"}) client.get("https://test_url") - requests = httpx_mock.get_requests(url=re.compile(".*test.*")) + requests = httpx2_mock.get_requests(url=re.compile(".*test.*")) assert len(requests) == 2 assert requests[0].headers["x-test"] == "1" assert "x-test" not in requests[1].headers -def test_callback_with_pattern_in_url(httpx_mock: HTTPXMock) -> None: +def test_callback_with_pattern_in_url(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) @@ -741,8 +741,8 @@ def custom_response2(request: httpx2.Request) -> httpx2.Response: json={"url": str(request.url)}, ) - httpx_mock.add_callback(custom_response, url=re.compile(".*test.*")) - httpx_mock.add_callback(custom_response2, url="https://unmatched") + httpx2_mock.add_callback(custom_response, url=re.compile(".*test.*")) + httpx2_mock.add_callback(custom_response2, url="https://unmatched") with httpx2.Client() as client: response = client.get("https://unmatched") @@ -752,33 +752,33 @@ def custom_response2(request: httpx2.Request) -> httpx2.Response: assert response.http_version == "HTTP/1.1" -def test_with_many_responses_urls_instances(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_many_responses_urls_instances(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param1": "test"}), method="GET", content=b"test content 1", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param2": "test"}), method="POST", content=b"test content 2", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param3": "test"}), method="PUT", content=b"test content 3", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param4": "test"}), method="DELETE", content=b"test content 4", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param5": "test"}), method="PATCH", content=b"test content 5", ) - httpx_mock.add_response( + httpx2_mock.add_response( url=httpx2.URL("https://test_url", params={"param6": "test"}), method="HEAD", content=b"test content 6", @@ -804,8 +804,8 @@ def test_with_many_responses_urls_instances(httpx_mock: HTTPXMock) -> None: assert response.content == b"test content 4" -def test_with_http_version_2(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_http_version_2(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", http_version="HTTP/2", content=b"test content 1" ) @@ -815,8 +815,8 @@ def test_with_http_version_2(httpx_mock: HTTPXMock) -> None: assert response.http_version == "HTTP/2" -def test_with_headers(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_with_headers(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", content=b"test content 1", headers={"X-Test": "Test value"}, @@ -830,23 +830,23 @@ def test_with_headers(httpx_mock: HTTPXMock) -> None: ) -def test_requests_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_requests_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", content=b"test content 1" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", content=b"test content 2" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PUT", content=b"test content 3" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="DELETE", content=b"test content 4" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="PATCH", content=b"test content 5" ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="HEAD", content=b"test content 6" ) @@ -858,95 +858,95 @@ def test_requests_retrieval(httpx_mock: HTTPXMock) -> None: client.patch("https://test_url", content=b"sent content 5") client.delete("https://test_url", headers={"X-Test": "test header 4"}) - patch_request = httpx_mock.get_request( + patch_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="PATCH" ) assert patch_request is not None assert patch_request.read() == b"sent content 5" - head_request = httpx_mock.get_request( + head_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="HEAD" ) assert head_request is not None assert head_request.read() == b"" - put_request = httpx_mock.get_request( + put_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="PUT" ) assert put_request is not None assert put_request.read() == b"sent content 3" - get_request = httpx_mock.get_request( + get_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="GET" ) assert get_request is not None assert get_request.headers["x-test"] == "test header 1" - post_request = httpx_mock.get_request( + post_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="POST" ) assert post_request is not None assert post_request.read() == b"sent content 2" - delete_request = httpx_mock.get_request( + delete_request = httpx2_mock.get_request( url=httpx2.URL("https://test_url"), method="DELETE" ) assert delete_request is not None assert delete_request.headers["x-test"] == "test header 4" -def test_requests_retrieval_on_same_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(url="https://test_url", is_reusable=True) +def test_requests_retrieval_on_same_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(url="https://test_url", is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) client.get("https://test_url", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests(url=httpx2.URL("https://test_url")) + requests = httpx2_mock.get_requests(url=httpx2.URL("https://test_url")) assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" -def test_request_retrieval_on_same_url(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_request_retrieval_on_same_url(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - request = httpx_mock.get_request(url=httpx2.URL("https://test_url")) + request = httpx2_mock.get_request(url=httpx2.URL("https://test_url")) assert request is not None assert request.headers["x-test"] == "test header 1" -def test_requests_retrieval_on_same_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_on_same_method(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests(method="GET") + requests = httpx2_mock.get_requests(method="GET") assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" -def test_request_retrieval_on_same_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_request_retrieval_on_same_method(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) client.post("https://test_url", headers={"X-TEST": "test header 2"}) - request = httpx_mock.get_request(method="GET") + request = httpx2_mock.get_request(method="GET") assert request is not None assert request.headers["x-test"] == "test header 1" -def test_requests_retrieval_on_same_url_and_method(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_on_same_url_and_method(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) @@ -954,46 +954,48 @@ def test_requests_retrieval_on_same_url_and_method(httpx_mock: HTTPXMock) -> Non client.post("https://test_url", headers={"X-TEST": "test header 3"}) client.get("https://test_url2", headers={"X-TEST": "test header 4"}) - requests = httpx_mock.get_requests(url=httpx2.URL("https://test_url"), method="GET") + requests = httpx2_mock.get_requests( + url=httpx2.URL("https://test_url"), method="GET" + ) assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" -def test_default_requests_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_default_requests_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.post("https://test_url", headers={"X-TEST": "test header 1"}) client.get("https://test_url2", headers={"X-TEST": "test header 2"}) - requests = httpx_mock.get_requests() + requests = httpx2_mock.get_requests() assert len(requests) == 2 assert requests[0].headers["x-test"] == "test header 1" assert requests[1].headers["x-test"] == "test header 2" -def test_default_request_retrieval(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response() +def test_default_request_retrieval(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response() with httpx2.Client() as client: client.post("https://test_url", headers={"X-TEST": "test header 1"}) - request = httpx_mock.get_request() + request = httpx2_mock.get_request() assert request is not None assert request.headers["x-test"] == "test header 1" -def test_requests_json_body(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_requests_json_body(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( url="https://test_url", method="GET", json=["list content 1", "list content 2"] ) - httpx_mock.add_response( + httpx2_mock.add_response( url="https://test_url", method="POST", json={"key 1": "value 1", "key 2": "value 2"}, ) - httpx_mock.add_response(url="https://test_url", method="PUT", json="string value") + httpx2_mock.add_response(url="https://test_url", method="PUT", json="string value") with httpx2.Client() as client: response = client.post("https://test_url") @@ -1009,14 +1011,14 @@ def test_requests_json_body(httpx_mock: HTTPXMock) -> None: assert response.headers["content-type"] == "application/json" -def test_callback_raising_exception(httpx_mock: HTTPXMock) -> None: +def test_callback_raising_exception(httpx2_mock: HTTPXMock) -> None: def raise_timeout(request: httpx2.Request) -> httpx2.Response: raise httpx2.ReadTimeout( f"Unable to read within {request.extensions['timeout']['read']}", request=request, ) - httpx_mock.add_callback(raise_timeout, url="https://test_url") + httpx2_mock.add_callback(raise_timeout, url="https://test_url") with httpx2.Client() as client: with pytest.raises(httpx2.ReadTimeout) as exception_info: @@ -1024,8 +1026,8 @@ def raise_timeout(request: httpx2.Request) -> httpx2.Response: assert str(exception_info.value) == "Unable to read within 5.0" -def test_request_exception_raising(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_exception( +def test_request_exception_raising(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_exception( httpx2.ReadTimeout("Unable to read within 5.0"), url="https://test_url" ) @@ -1036,8 +1038,8 @@ def test_request_exception_raising(httpx_mock: HTTPXMock) -> None: assert exception_info.value.request is not None -def test_non_request_exception_raising(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_exception( +def test_non_request_exception_raising(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_exception( httpx2.HTTPError("Unable to read within 5.0"), url="https://test_url" ) @@ -1047,11 +1049,11 @@ def test_non_request_exception_raising(httpx_mock: HTTPXMock) -> None: assert str(exception_info.value) == "Unable to read within 5.0" -def test_callback_returning_response(httpx_mock: HTTPXMock) -> None: +def test_callback_returning_response(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json={"url": str(request.url)}) - httpx_mock.add_callback(custom_response, url="https://test_url") + httpx2_mock.add_callback(custom_response, url="https://test_url") with httpx2.Client() as client: response = client.get("https://test_url") @@ -1060,11 +1062,11 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: @pytest.mark.parametrize("return_value", [None, "not a response"]) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_callback_not_returning_a_response( - httpx_mock: HTTPXMock, return_value: str | None + httpx2_mock: HTTPXMock, return_value: str | None ) -> None: - httpx_mock.add_callback(lambda request: return_value, url="https://test_url") + httpx2_mock.add_callback(lambda request: return_value, url="https://test_url") with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1075,11 +1077,11 @@ def test_callback_not_returning_a_response( ) -def test_callback_executed_twice(httpx_mock: HTTPXMock) -> None: +def test_callback_executed_twice(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_callback(custom_response, is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -1091,12 +1093,12 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: assert response.headers["content-type"] == "application/json" -def test_callback_registered_after_response(httpx_mock: HTTPXMock) -> None: +def test_callback_registered_after_response(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content2"]) - httpx_mock.add_response(json=["content1"]) - httpx_mock.add_callback(custom_response, is_reusable=True) + httpx2_mock.add_response(json=["content1"]) + httpx2_mock.add_callback(custom_response, is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -1113,12 +1115,12 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: assert response.headers["content-type"] == "application/json" -def test_response_registered_after_callback(httpx_mock: HTTPXMock) -> None: +def test_response_registered_after_callback(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content1"]) - httpx_mock.add_callback(custom_response) - httpx_mock.add_response(json=["content2"], is_reusable=True) + httpx2_mock.add_callback(custom_response) + httpx2_mock.add_response(json=["content2"], is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -1135,11 +1137,11 @@ def custom_response(request: httpx2.Request) -> httpx2.Response: assert response.headers["content-type"] == "application/json" -def test_callback_matching_method(httpx_mock: HTTPXMock) -> None: +def test_callback_matching_method(httpx2_mock: HTTPXMock) -> None: def custom_response(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(status_code=200, json=["content"]) - httpx_mock.add_callback(custom_response, method="GET", is_reusable=True) + httpx2_mock.add_callback(custom_response, method="GET", is_reusable=True) with httpx2.Client() as client: response = client.get("https://test_url") @@ -1159,14 +1161,14 @@ def test_request_retrieval_with_more_than_one(testdir: Testdir) -> None: import httpx2 - def test_request_retrieval_with_more_than_one(httpx_mock): - httpx_mock.add_response(is_reusable=True) + def test_request_retrieval_with_more_than_one(httpx2_mock): + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", headers={"X-TEST": "test header 1"}) client.get("https://test_url", headers={"X-TEST": "test header 2"}) - httpx_mock.get_request(url=httpx2.URL("https://test_url")) + httpx2_mock.get_request(url=httpx2.URL("https://test_url")) """) result = testdir.runpytest() result.assert_outcomes(failed=1) @@ -1177,8 +1179,8 @@ def test_request_retrieval_with_more_than_one(httpx_mock): ) -def test_headers_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +def test_headers_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={"User-Agent": f"python-httpx2/{httpx2.__version__}"} ) @@ -1187,8 +1189,8 @@ def test_headers_matching(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_headers={"my-custom-header": "value1, value2"}) +def test_multi_value_headers_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_headers={"my-custom-header": "value1, value2"}) with httpx2.Client() as client: response = client.get( @@ -1198,11 +1200,11 @@ def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None: assert response.content == b"" -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_multi_value_headers_not_matching_single_value_issued( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( match_headers={"my-custom-header": "value1"}, is_optional=True ) @@ -1222,11 +1224,11 @@ def test_multi_value_headers_not_matching_single_value_issued( ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) def test_multi_value_headers_not_matching_multi_value_issued( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response( + httpx2_mock.add_response( match_headers={"my-custom-header": "value1, value2"}, is_optional=True ) @@ -1246,9 +1248,9 @@ def test_multi_value_headers_not_matching_multi_value_issued( ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_headers_matching_respect_case(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={"user-agent": f"python-httpx2/{httpx2.__version__}"}, is_optional=True, ) @@ -1263,9 +1265,9 @@ def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None: ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_headers_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response( +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_headers_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response( match_headers={ "User-Agent": f"python-httpx2/{httpx2.__version__}", "Host": "test_url2", @@ -1284,24 +1286,24 @@ def test_headers_not_matching(httpx_mock: HTTPXMock) -> None: ) -def test_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_content=b"This is the body") +def test_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_content=b"This is the body") with httpx2.Client() as client: response = client.post("https://test_url", content=b"This is the body") assert response.read() == b"" -def test_proxy_matching_with_authentication(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") +def test_proxy_matching_with_authentication(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") with httpx2.Client(proxy="http://user:pwd@my_other_proxy") as client: response = client.get("https://test_url") assert response.read() == b"" -def test_proxy_matching_with_custom_proxy_headers(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy/") +def test_proxy_matching_with_custom_proxy_headers(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy/") with httpx2.Client( proxy=httpx2.Proxy("http://my_test_proxy", headers={"X-Something": "value"}) @@ -1311,9 +1313,9 @@ def test_proxy_matching_with_custom_proxy_headers(httpx_mock: HTTPXMock) -> None def test_proxy_matching_with_authentication_and_custom_proxy_headers( - httpx_mock: HTTPXMock, + httpx2_mock: HTTPXMock, ) -> None: - httpx_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") + httpx2_mock.add_response(proxy_url="http://user:pwd@my_other_proxy/") with httpx2.Client( proxy=httpx2.Proxy( @@ -1324,9 +1326,9 @@ def test_proxy_matching_with_authentication_and_custom_proxy_headers( assert response.read() == b"" -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_proxy_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_proxy_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) with httpx2.Client(proxy="http://my_test_proxy") as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1338,9 +1340,9 @@ def test_proxy_not_matching(httpx_mock: HTTPXMock) -> None: ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_proxy_not_existing(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_proxy_not_existing(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(proxy_url="http://my_test_proxy", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1352,30 +1354,30 @@ def test_proxy_not_existing(httpx_mock: HTTPXMock) -> None: ) -def test_requests_retrieval_content_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_content_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.post("https://test_url", content=b"This is the body") client.post("https://test_url2", content=b"This is the body") client.post("https://test_url2", content=b"This is the body2") - assert len(httpx_mock.get_requests(match_content=b"This is the body")) == 2 + assert len(httpx2_mock.get_requests(match_content=b"This is the body")) == 2 -def test_requests_retrieval_json_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_json_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.post("https://test_url", json=["my_str"]) client.post("https://test_url2", json=["my_str"]) client.post("https://test_url2", json=["my_str2"]) - assert len(httpx_mock.get_requests(match_json=["my_str"])) == 2 + assert len(httpx2_mock.get_requests(match_json=["my_str"])) == 2 -def test_requests_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_proxy_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client( mounts={ @@ -1388,12 +1390,12 @@ def test_requests_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: client.get("http://test_url2") assert ( - len(httpx_mock.get_requests(proxy_url="http://user:pwd@my_other_proxy/")) == 2 + len(httpx2_mock.get_requests(proxy_url="http://user:pwd@my_other_proxy/")) == 2 ) -def test_request_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_request_retrieval_proxy_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client( mounts={ @@ -1405,11 +1407,11 @@ def test_request_retrieval_proxy_matching(httpx_mock: HTTPXMock) -> None: client.get("https://test_url2") client.get("http://test_url2") - assert httpx_mock.get_request(proxy_url="http://my_test_proxy/") + assert httpx2_mock.get_request(proxy_url="http://my_test_proxy/") -def test_requests_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_files_and_data_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.put( @@ -1430,7 +1432,7 @@ def test_requests_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> No assert ( len( - httpx_mock.get_requests( + httpx2_mock.get_requests( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, ) @@ -1439,8 +1441,8 @@ def test_requests_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> No ) -def test_request_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_request_retrieval_files_and_data_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.put( @@ -1451,14 +1453,14 @@ def test_request_retrieval_files_and_data_matching(httpx_mock: HTTPXMock) -> Non client.get("https://test_url2") client.get("http://test_url2") - assert httpx_mock.get_request( + assert httpx2_mock.get_request( match_files={"name": ("file_name", b"File content")}, match_data={"field": "value"}, ) -def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_requests_retrieval_extensions_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url") @@ -1466,7 +1468,7 @@ def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: client.get("https://test_url2", timeout=10) assert ( len( - httpx_mock.get_requests( + httpx2_mock.get_requests( match_extensions={ "timeout": {"connect": 10, "read": 10, "write": 10, "pool": 10} } @@ -1476,22 +1478,22 @@ def test_requests_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: ) -def test_request_retrieval_extensions_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(is_reusable=True) +def test_request_retrieval_extensions_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(is_reusable=True) with httpx2.Client() as client: client.get("https://test_url", timeout=httpx2.Timeout(5, read=10)) client.get("https://test_url2", timeout=10) client.get("http://test_url2", timeout=10) - assert httpx_mock.get_request( + assert httpx2_mock.get_request( match_extensions={"timeout": {"connect": 5, "read": 10, "write": 5, "pool": 5}} ) -@pytest.mark.httpx_mock(assert_all_requests_were_expected=False) -def test_content_not_matching(httpx_mock: HTTPXMock) -> None: - httpx_mock.add_response(match_content=b"This is the body", is_optional=True) +@pytest.mark.httpx2_mock(assert_all_requests_were_expected=False) +def test_content_not_matching(httpx2_mock: HTTPXMock) -> None: + httpx2_mock.add_response(match_content=b"This is the body", is_optional=True) with httpx2.Client() as client: with pytest.raises(httpx2.TimeoutException) as exception_info: @@ -1503,9 +1505,9 @@ def test_content_not_matching(httpx_mock: HTTPXMock) -> None: ) -def test_match_json_and_match_content_error(httpx_mock: HTTPXMock) -> None: +def test_match_json_and_match_content_error(httpx2_mock: HTTPXMock) -> None: with pytest.raises(ValueError) as exception_info: - httpx_mock.add_response(match_json={"a": 1}, match_content=b"