Skip to content

Warning

This is the documentaion of the older version 0.14.0. See latest for current release.

Mock HTTPX - Version 0.14.0

To mock out HTTPX and/or HTTP Core, use the respx.mock decorator / context manager.

Optionally configure built-in assertion checks and base URL with respx.mock(...).

Using the Decorator

import httpx
import respx


@respx.mock
def test_something():
    request = respx.get("https://foo.bar/", content="foobar")
    response = httpx.get("https://foo.bar/")
    assert request.called
    assert response.status_code == 200
    assert response.text == "foobar"

Using the Context Manager

import httpx
import respx


with respx.mock:
    request = respx.get("https://foo.bar/", content="foobar")
    response = httpx.get("https://foo.bar/")
    assert request.called
    assert response.status_code == 200
    assert response.text == "foobar"

NOTE

You can also start and stop mocking HTTPX manually, by calling respx.start() and respx.stop().

Using the mock Transports

The built-in transports are the base of all mocking and patching in RESPX.

In fact, respx.mock is an actual instance of MockTransport.

MockTransport

import httpx
import respx


mock_transport = respx.MockTransport()
request = mock_transport.get("https://foo.bar/", content="foobar")

with mock_transport:
    response = httpx.get("https://foo.bar/")
    assert request.called
    assert response.status_code == 200
    assert response.text == "foobar"

SyncMockTransport

If you don't need to patch the original HTTPX/HTTP Core transports, then use the SyncMockTransport or AsyncMockTransport directly, by passing the transport arg when instantiating your HTTPX client, or alike.

import httpx
import respx


mock_transport = respx.SyncMockTransport()
request = mock_transport.get("https://foo.bar/", content="foobar")

with httpx.Client(transport=mock_transport) as client:
    response = client.get("https://foo.bar/")
    assert request.called
    assert response.status_code == 200
    assert response.text == "foobar"

AsyncMockTransport

import httpx
import respx


mock_transport = respx.AsyncMockTransport()
request = mock_transport.get("https://foo.bar/", content="foobar")

async with httpx.AsyncClient(transport=mock_transport) as client:
    response = await client.get("https://foo.bar/")
    assert request.called
    assert response.status_code == 200
    assert response.text == "foobar"

NOTE

The mock transports takes the same configuration arguments as the decorator / context manager.

Global Setup & Teardown

pytest

# conftest.py
import pytest
import respx


@pytest.fixture
def mocked_api():
    with respx.mock(base_url="https://foo.bar") as respx_mock:
        respx_mock.get("/users/", content=[], alias="list_users")
        ...
        yield respx_mock
# test_api.py
import httpx


def test_list_users(mocked_api):
    response = httpx.get("https://foo.bar/users/")
    request = mocked_api["list_users"]
    assert request.called
    assert response.json() == []

Tip

Use a session scoped fixture @pytest.fixture(scope="session") when your fixture contains multiple endpoints that not necessary gets called by a single test case, or disable the built-in assert_all_called check.

unittest

# testcases.py

class MockedAPIMixin:
    def setUp(self):
        self.mocked_api = respx.mock(base_url="https://foo.bar")
        self.mocked_api.get("/users/", content=[], alias="list_users")
        ...
        self.mocked_api.start()

    def tearDown(self):
        self.mocked_api.stop()
# test_api.py

import unittest
import httpx

from .testcases import MockedAPIMixin


class MyTestCase(MockedAPIMixin, unittest.TestCase):
    def test_list_users(self):
        response = httpx.get("https://foo.bar/users/")
        request = self.mocked_api["list_users"]
        assert request.called
        assert response.json() == []

Tip

Use setUpClass and tearDownClass when you mock multiple endpoints that not necessary gets called by a single test method, or disable the built-in assert_all_called check.

Async Support

You can use respx.mock in both sync and async contexts to mock out HTTPX responses.

pytest

@respx.mock
@pytest.mark.asyncio
async def test_something():
    async with httpx.AsyncClient() as client:
        request = respx.get("https://foo.bar/", content="foobar")
        response = await client.get("https://foo.bar/")
        assert request.called
        assert response.text == "foobar"
@pytest.mark.asyncio
async def test_something():
    async with respx.mock:
        async with httpx.AsyncClient() as client:
            request = respx.get("https://foo.bar/", content="foobar")
            response = await client.get("https://foo.bar/")
            assert request.called
            assert response.text == "foobar"

Session Scoped Fixtures

If a session scoped RESPX fixture is used in an async context, you also need to broaden the pytest-asyncio event_loop fixture. You can use the session_event_loop utility for this.

# conftest.py

import pytest
import respx
from respx.fixtures import session_event_loop as event_loop  # noqa: F401


@pytest.fixture(scope="session")
async def mocked_api(event_loop):  # noqa: F811
    async with respx.mock(base_url="https://foo.bar") as respx_mock:
        ...
        yield respx_mock

unittest

import asynctest


class MyTestCase(asynctest.TestCase):
    @respx.mock
    async def test_something(self):
        async with httpx.AsyncClient() as client:
            request = respx.get("https://foo.bar/", content="foobar")
            response = await client.get("https://foo.bar/")
            assert request.called
            assert response.text == "foobar"

    async def test_something(self):
        async with respx.mock:
            async with httpx.AsyncClient() as client:
                request = respx.get("https://foo.bar/", content="foobar")
                response = await client.get("https://foo.bar/")
                assert request.called
                assert response.text == "foobar"