Giter Site home page Giter Site logo

Add request matching about aioresponses HOT 3 OPEN

paulschmeida avatar paulschmeida commented on June 1, 2024 6
Add request matching

from aioresponses.

Comments (3)

hydrargyrum avatar hydrargyrum commented on June 1, 2024 1

I have the same problem, it does not seem possible, matching is only based on method+URL: https://github.com/pnuckowski/aioresponses/blob/master/aioresponses/core.py#L118

The sync counterpart libs can do it though, maybe it could be an inspiration for aioresponses?

from aioresponses.

Kylmakalle avatar Kylmakalle commented on June 1, 2024

I somehow reproduced the responses match logic with a callback. You'll need a single callback for all of the similar URLs you can't distinguish with basic match

import responses

with responses.RequestsMock() as rsps:
    rsps.add(
        responses.POST,
        'https://url/',
        json={"status": 1, "error": None},
        status=200,
        match=[responses.urlencoded_params_matcher({"verbose": "1", "data": '{"foo":"bar"}'})],
    )

aioresponses

from aioresponses import aioresponses, CallbackResult

with aioresponses() as rsps:
    def callback(url, **kwargs):
        if kwargs['data'] == {"verbose": 1, "data": '{"foo":"bar"}'}:
            pass
        elif:
            raise Exception("Unable to match the request")
        
    rsps.post(
        'https://url/',
        body=json.dumps({"status": 1, "error": None}),
        status=200,
        callback=callback
    )

Returning CallbackResult in the callback, you can provide your own CallbackResult implementation to add a resolved json field based on the request provided.

from aioresponses import aioresponses, CallbackResult

with aioresponses() as rsps:

    def callback(url, **kwargs):
        if kwargs['data'] == {"verbose": 1, "data": '{"foo":"bar"}'}:
            return CallbackResult(json={"status": 1, "error": None})
        elif:
            raise Exception("Unable to match the request")
    
    rsps.post(
        'https://url/',
        status=200,
        callback=callback
    )

from aioresponses.

CrypticGuru avatar CrypticGuru commented on June 1, 2024

I accomplished this by writing a custom (reusable) function which matches any kwargs given to the request.
It is contained in the following script, which you can run yourself (just make sure your filename has test_ prepended, for pytest).

import aiohttp
import aioresponses
import pytest
import typing
import yarl



def _aio_match_any(
    requests: typing.Dict[
        typing.Tuple['str', yarl.URL],
        typing.List[aioresponses.core.RequestCall]
    ],
    method: typing.Literal['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'],
    url: str,
    **kwargs
) -> None:
    """
    Match any arbitrary keyword parameters given to an `aiohttp.request`.

    Meant to be tacked-on to the `aio` fixture, but can be imported and used directly if needed.

    Args:
        requests (dict): The aioresponses.aioresponses.requests dict.
        method (str): The request HTTP method.
        url (str): The URL of the request to match.
        kwargs: Any key/value pair to match against

    Raises:
        (KeyError): If the combination of (method, url) does not exist in the provided requests.
        (AssertionError): If the provided **kwargs do not match.

    """
    matches = requests[(method.upper(), yarl.URL(url))]  # can intentionally raise a KeyError
    matched = matches[0]  # there might be others, this only works with the first request currently
    for key, value in kwargs.items():
        if (actual := matched.kwargs.get(key)) != value:
            raise AssertionError(f'Expected "{key}" to be {value}, got {actual} instead.')


@pytest.fixture
def aio():
    """Fixture for mocking aiohttp.request calls."""
    with aioresponses.aioresponses() as m:
        m.match_any = _aio_match_any  # `_aio_match_any` attached for ease-of-use within tests!
        yield m


@pytest.mark.asyncio
async def test_param(aio):
    async with aiohttp.ClientSession() as session:
        aio.post('http://test.example.com')
        await session.post('http://test.example.com', json={'expected': 'json'})
        aio.match_any(aio.requests, 'POST', 'http://test.example.com', json={'expected': 'json'})


pytest.main([__file__])

from aioresponses.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.