Colin-b/pytest_httpx

Support for httpx > 0.17.x

Closed this issue · 3 comments

httpx released a new version. Currently the httpx is limited to 0.17.*.

It would be nice if pytest-httpx is updated.

Thanks

Thanks for reporting.

pytest-httpx 0.12.0 now requires httpx==0.18.*

Trying to run the tests for PyRMVtransport with httpx==0.18.0 and pytest-httpx==0.12.0 and I'm running into the following incompatibility still:

============================= test session starts ==============================
platform linux -- Python 3.8.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /build/source
plugins: asyncio-0.14.0, httpx-0.12.0
collected 15 items

tests/test_bugs.py ..                                                    [ 13%]
tests/test_rmvtransport.py ..xxxx.xx..xF                                 [100%]

=================================== FAILURES ===================================
___________________________ test__query_rmv_api_fail ___________________________

httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x7ffff5773670>

    @pytest.mark.asyncio
    @pytest.mark.xfail(raises=RMVtransportError)
    async def test__query_rmv_api_fail(httpx_mock):
        """Test failing station search."""

        def raise_timeout(request, ext: dict):
            raise httpx.ReadTimeout(
                f"Unable to read within {ext['timeout']}", request=request
            )

        httpx_mock.add_callback(raise_timeout)

        with pytest.raises(httpx.ReadTimeout):
            rmv = RMVtransport(timeout=0.005)

            url = f"https://{URL}{URL_SEARCH_PATH}"
>           await rmv._query_rmv_api(url)

tests/test_rmvtransport.py:219:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
RMVtransport/rmvtransport.py:153: in _query_rmv_api
    response = await client.get(url)
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1662: in get
    return await self.request(
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1426: in request
    response = await self.send(
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1511: in send
    response = await self._send_handling_auth(
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1546: in _send_handling_auth
    response = await self._send_handling_redirects(
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1580: in _send_handling_redirects
    response = await self._send_single_request(request, timeout)
/nix/store/a869sns3k418f310cs94qm3qw1178mib-python3.8-httpx-0.18.0/lib/python3.8/site-packages/httpx/_client.py:1621: in _send_single_request
    ) = await transport.handle_async_request(
/nix/store/d4zi55m70c468pnybqlykych3s5mgzl0-python3.8-pytest-httpx-0.12.0/lib/python3.8/site-packages/pytest_httpx/_httpx_mock.py:335: in handle_async_request
    return self.mock._handle_request(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pytest_httpx._httpx_mock.HTTPXMock object at 0x7ffff5773670>
method = b'GET'
url = (b'https', b'www.rmv.de', None, b'/auskunft/bin/jp/ajax-getstop.exe/dn')
headers = [(b'Host', b'www.rmv.de'), (b'Accept', b'*/*'), (b'Accept-Encoding', b'gzip, deflate, br'), (b'Connection', b'keep-alive'), (b'User-Agent', b'python-httpx/0.18.0')]
stream = <httpx.ByteStream object at 0x7ffff5b6aca0>
extensions = {'timeout': {'connect': 5.0, 'pool': 5.0, 'read': 5.0, 'write': 5.0}}

    def _handle_request(
        self,
        method: bytes,
        url: URL,
        headers: Headers = None,
        stream: Union[httpcore.SyncByteStream, httpcore.AsyncByteStream] = None,
        extensions: dict = None,
    ) -> Response:
        request = to_request(method, url, headers, stream)
        self._requests.append(request)

        response = self._get_response(request)
        if response:
            return response

        callback = self._get_callback(request)
        if callback:
>           return callback(request=request, extensions=extensions)
E           TypeError: raise_timeout() got an unexpected keyword argument 'extensions'

/nix/store/d4zi55m70c468pnybqlykych3s5mgzl0-python3.8-pytest-httpx-0.12.0/lib/python3.8/site-packages/pytest_httpx/_httpx_mock.py:179: TypeError
=========================== short test summary info ============================
FAILED tests/test_rmvtransport.py::test__query_rmv_api_fail - TypeError: rais...
==================== 1 failed, 7 passed, 7 xfailed in 0.70s ====================

Yes, as stated in changelog you have to rename ext parameter into extensions. This information is of course also available in the documentation.

So your test case should be modified:

@pytest.mark.asyncio
@pytest.mark.xfail(raises=RMVtransportError)
async def test__query_rmv_api_fail(httpx_mock):
    """Test failing station search."""

    def raise_timeout(request, extensions: dict):
        raise httpx.ReadTimeout(
            f"Unable to read within {extensions['timeout']}", request=request
        )

    httpx_mock.add_callback(raise_timeout)

    with pytest.raises(httpx.ReadTimeout):
        rmv = RMVtransport(timeout=0.005)

        url = f"https://{URL}{URL_SEARCH_PATH}"
        await rmv._query_rmv_api(url)

Note that what you are mocking is actually the exact behavior of the mock by default, you should be able to modify your test this way and have the same behavior:

@pytest.mark.asyncio
@pytest.mark.xfail(raises=RMVtransportError)
async def test__query_rmv_api_fail(httpx_mock):
    """Test failing station search."""
    with pytest.raises(httpx.ReadTimeout):
        rmv = RMVtransport(timeout=0.005)

        url = f"https://{URL}{URL_SEARCH_PATH}"
        await rmv._query_rmv_api(url)

Best Regards