Confusion around assert_all_mocked behavior
sihrc opened this issue · 2 comments
sihrc commented
@respx.mock(assert_all_mocked=True)
async def test_httpx_all_mocked_true():
async with httpx.AsyncClient() as client:
request = respx.get("http://test.com/id").mock(
return_value=httpx.Response(200, content="test")
)
resp = await client.get("http://test.com/id")
assert resp.content == b"test"
@respx.mock(assert_all_mocked=False)
async def test_httpx_all_mocked_false():
async with httpx.AsyncClient() as client:
request = respx.get("http://test.com/id").mock(
return_value=httpx.Response(200, content="test")
)
resp = await client.get("http://test.com/id")
assert resp.content == b"test"
@respx.mock
async def test_httpx_all_mocked_none():
async with httpx.AsyncClient() as client:
request = respx.get("http://test.com/id").mock(
return_value=httpx.Response(200, content="test")
)
resp = await client.get("http://test.com/id")
assert resp.content == b"test"
Given these 3 identical tests with different assert_all_mocked inputs, here is the output:
================================== FAILURES ==================================
_________________________ test_httpx_all_mocked_true _________________________
@respx.mock(assert_all_mocked=True)
async def test_httpx_all_mocked_true():
async with httpx.AsyncClient() as client:
request = respx.get("http://test.com/id").mock(
return_value=httpx.Response(200, content="test")
)
> resp = await client.get("http://test.com/id")
tests/routes/test_twitch_users_routes.py:19:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1729: in get
return await self.request(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1506: in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1593: in send
response = await self._send_handling_auth(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1621: in _send_handling_auth
response = await self._send_handling_redirects(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1658: in _send_handling_redirects
response = await self._send_single_request(request)
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1695: in _send_single_request
response = await transport.handle_async_request(request)
/usr/local/lib/python3.10/site-packages/httpx/_transports/default.py:353: in handle_async_request
resp = await self._pool.handle_async_request(req)
/usr/local/lib/python3.10/site-packages/respx/mocks.py:188: in amock
response = await cls._send_async_request(
/usr/local/lib/python3.10/site-packages/respx/mocks.py:222: in _send_async_request
httpx_response = await cls.async_handler(httpx_request)
/usr/local/lib/python3.10/site-packages/respx/mocks.py:134: in async_handler
raise assertion_error
/usr/local/lib/python3.10/site-packages/respx/mocks.py:127: in async_handler
httpx_response = await router.async_handler(httpx_request)
/usr/local/lib/python3.10/site-packages/respx/router.py:319: in async_handler
resolved = await self.aresolve(request)
/usr/local/lib/python3.10/site-packages/respx/router.py:292: in aresolve
with self.resolver(request) as resolved:
/usr/local/lib/python3.10/contextlib.py:142: in __exit__
next(self.gen)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <respx.router.MockRouter object at 0x7f87b1b2b9a0>
request = <Request('GET', 'http://test.com/id')>
@contextmanager
def resolver(self, request: httpx.Request) -> Generator[ResolvedRoute, None, None]:
resolved = ResolvedRoute()
try:
yield resolved
if resolved.route is None:
# Assert we always get a route match, if check is enabled
if self._assert_all_mocked:
> raise AllMockedAssertionError(f"RESPX: {request!r} not mocked!")
E respx.models.AllMockedAssertionError: RESPX: <Request('GET', 'http://test.com/id')> not mocked!
/usr/local/lib/python3.10/site-packages/respx/router.py:251: AllMockedAssertionError
________________________ test_httpx_all_mocked_false _________________________
@respx.mock(assert_all_mocked=False)
async def test_httpx_all_mocked_false():
async with httpx.AsyncClient() as client:
request = respx.get("http://test.com/id").mock(
return_value=httpx.Response(200, content="test")
)
resp = await client.get("http://test.com/id")
> assert resp.content == b"test"
E AssertionError: assert b'' == b'test'
E Full diff:
E - b'test'
E + b''
tests/routes/test_twitch_users_routes.py:31: AssertionError
========================== short test summary info ===========================
FAILED tests/routes/test_twitch_users_routes.py::test_httpx_all_mocked_true
FAILED tests/routes/test_twitch_users_routes.py::test_httpx_all_mocked_false
======================== 2 failed, 1 passed in 0.53s =========================
Shouldn't all of these tests pass if the tests are identical and rely on the mock?
Also, I see that the default assert_all_mocked value is True. Why is it that the behavior of not passing in a value is different from passing in True?
sihrc commented
Furthermore, it appears passing in anything to the respx.mock decorator changes behavior:
e.g.
@respx.mock(base_url="http://example.com")
async def test_with_base_url():
async with httpx.AsyncClient() as client:
respx.get("/user").mock(return_value=httpx.Response(200, content="test"))
resp = await client.get("http://example.com/user")
assert resp.content == b"test"
@respx.mock
async def test_without_base_url():
async with httpx.AsyncClient() as client:
respx.get("http://example.com/user").mock(
return_value=httpx.Response(200, content="test")
)
resp = await client.get("http://example.com/user")
assert resp.content == b"test"
Results in:
================================== FAILURES ==================================
_____________________________ test_with_base_url _____________________________
@respx.mock(base_url="http://example.com")
async def test_with_base_url():
async with httpx.AsyncClient() as client:
respx.get("/user").mock(return_value=httpx.Response(200, content="test"))
> resp = await client.get("http://example.com/user")
tests/routes/test_twitch_users_routes.py:9:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1729: in get
return await self.request(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1506: in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1593: in send
response = await self._send_handling_auth(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1621: in _send_handling_auth
response = await self._send_handling_redirects(
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1658: in _send_handling_redirects
response = await self._send_single_request(request)
/usr/local/lib/python3.10/site-packages/httpx/_client.py:1695: in _send_single_request
response = await transport.handle_async_request(request)
/usr/local/lib/python3.10/site-packages/httpx/_transports/default.py:353: in handle_async_request
resp = await self._pool.handle_async_request(req)
/usr/local/lib/python3.10/site-packages/respx/mocks.py:188: in amock
response = await cls._send_async_request(
/usr/local/lib/python3.10/site-packages/respx/mocks.py:222: in _send_async_request
httpx_response = await cls.async_handler(httpx_request)
/usr/local/lib/python3.10/site-packages/respx/mocks.py:134: in async_handler
raise assertion_error
/usr/local/lib/python3.10/site-packages/respx/mocks.py:127: in async_handler
httpx_response = await router.async_handler(httpx_request)
/usr/local/lib/python3.10/site-packages/respx/router.py:319: in async_handler
resolved = await self.aresolve(request)
/usr/local/lib/python3.10/site-packages/respx/router.py:292: in aresolve
with self.resolver(request) as resolved:
/usr/local/lib/python3.10/contextlib.py:142: in __exit__
next(self.gen)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <respx.router.MockRouter object at 0x7fb4d9417d30>
request = <Request('GET', 'http://example.com/user')>
@contextmanager
def resolver(self, request: httpx.Request) -> Generator[ResolvedRoute, None, None]:
resolved = ResolvedRoute()
try:
yield resolved
if resolved.route is None:
# Assert we always get a route match, if check is enabled
if self._assert_all_mocked:
> raise AllMockedAssertionError(f"RESPX: {request!r} not mocked!")
E respx.models.AllMockedAssertionError: RESPX: <Request('GET', 'http://example.com/user')> not mocked!
/usr/local/lib/python3.10/site-packages/respx/router.py:251: AllMockedAssertionError
========================== short test summary info ===========================
FAILED tests/routes/test_twitch_users_routes.py::test_with_base_url - respx...
======================== 1 failed, 1 passed in 0.44s =========================```