aioresponses icon indicating copy to clipboard operation
aioresponses copied to clipboard

Make headers sent to mocked endpoint available as part of requests

Open mjhanke opened this issue 6 years ago • 4 comments

@aioresponses
fn(mock):
    mock.post(url, status=200)
    method_that_calls_url_with_headers()

    print(mock.requests[('POST', URL(url))][0].kwargs['headers'])

Currently, only args, kwargs are available for a request to a particular (method, url) tuple.

It would be nice to be able to access what headers were sent to a mocked endpoint. Hopefully it's as simple as adding it as a field in kwargs

mjhanke avatar Dec 11 '18 20:12 mjhanke

Hi,

I would like this feature as well but it does not seems as straightforward.

Would it be possible to mimic the behavior of aiohttp in order to also get the default headers that might be set on the underlying session?

The easy and fast way of doing it would be to add "orig_self" variable to the saved request (and then check "_default_headers" on this instance) as it is available but I think that from a user perspective it's better to provide headers as if a real call was performed.

What do you think @pnuckowski, do you have a design in mind?

Colin-b avatar Dec 02 '19 15:12 Colin-b

You can read request headers like so:

with aioresponses() as m:
    m.get("http://localhost:123/collection.txt", status=200)

    yield  # actual test code / requests here.

    for _, requests in m.requests.items():
        assert "vdirsyncer" in requests[0].kwargs['headers']['User-Agent']

You can also just use a callback if you want to assert your headers.

WhyNotHugo avatar Jun 22 '21 18:06 WhyNotHugo

Unfortunately, this approach doesn't seem to work if the headers are set on the ClientSession, not in the individual call, which I suspect is what triggered the bug report. Also see #187.

In other words, you don't see the headers if the client code looks like this:

session = aiohttp.ClientSession(headers={"Foo": "bar"})
session.get("http://localhost:123/collection.txt")

rra avatar Jul 19 '21 17:07 rra

A workaround for checking a header set on ClientSession - define callback on your mock and traverse through stack until you get orig_self variable (3 frames in aioresponses version I use)

def callback(url, **kwargs):
    assert 'Bearer xyz' == sys._getframe(3).f_locals['orig_self'].headers['Authorization']
    return CallbackResult(status=200, payload={})
mocked.get('http://url', callback=callback)

alex-kowalczyk avatar Aug 11 '21 07:08 alex-kowalczyk