pnuckowski / aioresponses

Aioresponses is a helper for mock/fake web requests in python aiohttp package.
MIT License
513 stars 86 forks source link

Proposal: implement aioresponses.assert_has_calls #253

Open KeNaCo opened 9 months ago

KeNaCo commented 9 months ago

First, thank you for your effort in maintaining the library.

Context

I would like to assert, that a series of requests happen in a particular order. With current API it's not possible to do such assertion. So I propose to extend aioresponses with the assert_has_calls(calls) method.

Problem

In my case, I need to assert that various URLs are called (multiple times each) in a particular order. aioresponses currently doesn't provide any method that can help. The class has the public attribute aioresponses.requests, but it's implemented as a dict, and the exact call order cannot be determined.

Solution

I propose the implementation of aioresponses.assert_has_calls(calls, any_order=False) method, that behaves similarly to the standard Mock implementation. I would suggest that the method will accept unittest.mock.call objects, but dedicated request(...) object is an option.

Example of use:

calls = [
    call("http://domian.com/"),
    call("http://domain.com/", method="GET"),
    call("http://domain.com/", params={"a":1, "b":2}),
    call(URL("http://domain.com/")),
]
aioresponses.assert_has_calls(calls)
KeNaCo commented 9 months ago

I'm willing to implement it and send PR, but before anyone's time is wasted I would like to get :+1: from maintainers and implementation preference:

minimal PR Functionality will be implemented next to the existing one. This will be less amount of changes in PR, but the library will have two separate tracking approaches for calls.

clean code Existing functionality will be refactored to work with one history tracking. Should produce cleaner code for the price of harder review in PR. This negative can be (subjectively) mitigated by splitting changes into a few smaller PRs.

I would also like to ask about aioresponses.requests. It's not mentioned in the documentation, but the attribute is public and someone may depend on it. It can be replaced with property transforming new list representation into dict, I just wanto to know if it's part of the requirements.

Thank you for any answers in advance.

mark-meyer commented 6 months ago

FWIW, I just came here searching for this. I assumed this would support the more or less the same assertions that unittest.mock supports and properties like call_count. I have no standing to give a thumbs up, but you certainly have my vote.