A mocking library for requests

Overview

httmock

A mocking library for requests for Python 2.7 and 3.4+.

Installation

pip install httmock

Or, if you are a Gentoo user:

emerge dev-python/httmock

Usage

You can use it to mock third-party APIs and test libraries that use requests internally, conditionally using mocked replies with the urlmatch decorator:

from httmock import urlmatch, HTTMock
import requests

@urlmatch(netloc=r'(.*\.)?google\.com$')
def google_mock(url, request):
    return 'Feeling lucky, punk?'

with HTTMock(google_mock):
    r = requests.get('http://google.com/')
print r.content  # 'Feeling lucky, punk?'

The all_requests decorator doesn't conditionally block real requests. If you return a dictionary, it will map to the requests.Response object returned:

from httmock import all_requests, HTTMock
import requests

@all_requests
def response_content(url, request):
	return {'status_code': 200,
	        'content': 'Oh hai'}

with HTTMock(response_content):
	r = requests.get('https://foo_bar')

print r.status_code
print r.content

If you pass in Set-Cookie headers, requests.Response.cookies will contain the values. You can also use response method directly instead of returning a dict:

from httmock import all_requests, response, HTTMock
import requests

@all_requests
def response_content(url, request):
	headers = {'content-type': 'application/json',
	           'Set-Cookie': 'foo=bar;'}
	content = {'message': 'API rate limit exceeded'}
	return response(403, content, headers, None, 5, request)

with HTTMock(response_content):
	r = requests.get('https://api.github.com/users/whatever')

print r.json().get('message')
print r.cookies['foo']
Comments
  • make urlmatch optionally filter based on request method

    make urlmatch optionally filter based on request method

    More REST compliant services have the same URL for different operations and the difference between them is the HTTP method. This change allows multiple functions to mock the same URL but for different HTTP methods i.e. GET vs POST can be mocked separately for the same URL.

    It maintains previous behaviour so if a function doesn't specify the method param and multiple functions match the same URL the first one to return a value that's not None is taken.

    opened by zcourts 5
  • Is it possible to mock connection errors?

    Is it possible to mock connection errors?

    >>> import requests
    >>> requests.get('http://fake.fake')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 55, in get
        return request('get', url, **kwargs)
      File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 44, in request
        return session.request(method=method, url=url, **kwargs)
      File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 383, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 486, in send
        r = adapter.send(request, **kwargs)
      File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 378, in send
        raise ConnectionError(e)
    requests.exceptions.ConnectionError: HTTPConnectionPool(host='fake.fake', port=80): Max retries exceeded with url: / (Caused by <class 'socket.gaierror'>: [Errno 8] nodename nor servname provided, or not known)
    

    I want to throw the ConnectionError above.

    opened by dhalperi 4
  • Provide mock with a Request, not PreparedRequest

    Provide mock with a Request, not PreparedRequest

    Providing a Request instead of a PreparedRequest would make complicated mocking much easier: Request basically holds the kwargs to requests.method, while PreparedRequest only stores encoded versions of the kwargs.

    For example, if you'd like to replay request params (maybe when testing an OAuth flow), PreparedRequest requires reparsing request.path_url, while Request would provide request.params directly.

    opened by simon-weber 4
  • Give the response some context, just like requests does.

    Give the response some context, just like requests does.

    See https://github.com/kennethreitz/requests/blob/master/requests/adapters.py#L180-L189.

    I'm using httmock to test a new API wrapper and checking the internals of the request object to ensure that my wrapper is setting up the calls correctly. In https://github.com/kennethreitz/requests/blob/master/requests/adapters.py#L180-L189 , requests adds both the request and request.url as attributes on the response. This does the same.

    opened by jnovinger 4
  • Added a request list to remember_called decorator

    Added a request list to remember_called decorator

    I need to assert the payload sent to an external host, so I added the request list in order to ensure my data was properly formed.

    The scenario it's a functional tests with no integration servers. I need to test a call to an api, although it's my code I consider it as a blackbox. this blackbox must to do a call to another api so I have not direct way to validate the third call. Using the request history I can validate the call. Something like this:

    def test_store_several_requests(self):
        with HTTMock(google_mock_store_requests):
            payload = {"query": "foo"}
            requests.post('http://google.com', data=payload)
    
        self.assertTrue(google_mock_store_requests.call['called'])
        self.assertEqual(google_mock_store_requests.call['count'], 1)
        request = google_mock_store_requests.call['requests'][0]
        self.assertEqual(request.body, 'query=foo')
    
    opened by jsenin 3
  • Provide access to the Request object from the PreparedRequest.original attribute

    Provide access to the Request object from the PreparedRequest.original attribute

    As issue #16 points out, the PreparedRequest object is not always very useful. So, provide a original attribute so you can access the originating Request object.

    opened by dummerbd 3
  • Fix redirect handling

    Fix redirect handling

    This adds support for:

    • mocking out a redirect
    • redirecting to a mock

    Basically, I just copy/pasted the redirect-handling part of session.send into the fake send code. I had to fake Response.close as well.

    opened by simon-weber 3
  • Conditionally encode the response for Python 3.2 and Python 3.3 to work properly

    Conditionally encode the response for Python 3.2 and Python 3.3 to work properly

    Without the encoding, requests will bomb out in Python 3 with:

    Traceback (most recent call last):
        self.assertEqual(self.content, response.json())
      File "/home/travis/virtualenv/python3.2/lib/python3.2/site-packages/requests/models.py", line 687, in json
        encoding = guess_json_utf(self.content)
      File "/home/travis/virtualenv/python3.2/lib/python3.2/site-packages/requests/utils.py", line 518, in guess_json_utf
        nullcount = sample.count(_null)
    TypeError: Can't convert 'bytes' object to str implicitly
    
    opened by gmr 3
  • Problem with requests and iter_lines

    Problem with requests and iter_lines

    I am trying to mock a response for requests but httmock breaks iter_lines from requests.

    With

    import requests
    from httmock import urlmatch, HTTMock
    
    
    @urlmatch(netloc=r'uw.edu')
    def local_mock(url, request):
        return {'status_code': 200, 'content': 'Hello, World'}
    
    
    def main():
        with HTTMock(local_mock):
            print list(requests.get('http://uw.edu').iter_lines())
    
    if __name__ == '__main__':
        main()
    

    I get the following error

    Traceback (most recent call last):
      File "mock_bug.py", line 15, in <module>
        main()
      File "mock_bug.py", line 12, in main
        print list(requests.get('http://uw.edu').iter_lines())
      File ".../python2.7/site-packages/requests/models.py", line 648, in iter_lines
        decode_unicode=decode_unicode):
      File ".../python2.7/site-packages/requests/models.py", line 625, in generate
        chunk = self.raw.read(chunk_size)
    AttributeError: 'NoneType' object has no attribute 'read'
    

    Running the same code without the mock works fine.

    opened by domoritz 2
  • mock by request method

    mock by request method

    Perhaps I am mistaken, but it looks like your library does not support mocking by method, e.g. how would you distinguish between a GET and a POST with the same request url?

    opened by kevinludwig 2
  • No longer works with mock objects

    No longer works with mock objects

    The 1.1.0 release no longer works when used as the return value for a mock object.

    Failing test case:

    class PutTest(unittest.TestCase):
        def test_put(self):
            res = httmock.response(status_code=204)
            put_mock = mock.Mock()
            put_mock.return_value = res
            response = put_mock('http://example.org', data={'foo', 'bar'})
    

    Fails with an exception:

    ======================================================================
    ERROR: test_put (main.PutTest)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/Users/jimrollenhagen/code/httmock-bug/main.py", line 13, in test_put
        res = httmock.response(status_code=204)
      File "/Users/jimrollenhagen/virtualenvs/httmockbug/lib/python2.7/site-packages/httmock.py", line 43, in response
        res.url = request.url
    AttributeError: 'NoneType' object has no attribute 'url'
    
    ----------------------------------------------------------------------
    
    opened by jimrollenhagen 2
  • Test with GitHub Actions

    Test with GitHub Actions

    Includes #64.

    Travis CI has a new pricing model making it harder to test open source projects, and it's also stopped running.

    This PR add testing on GitHub Actions.

    Pros

    • 20 parallel jobs, not 5 like Travis
    • Can test on Windows and macOS, not just Ubuntu
    • Very flexible, lots of extra actions (aka add-ons) available
    • The new popular CI for Python projects
    • No confusing pricing model

    Cons

    • Does not have ppc64le architecture
    • Does not have EOL Python 3.4 (I would recommend dropping EOL 2.7 and 3.4-3.6)

    If ppc64le isn't important, I'd recommend deleting .travis.yml outright.

    Demo

    https://github.com/hugovk/httmock/actions/runs/1677534178

    opened by hugovk 0
  • Add tox.ini to make local testing easy

    Add tox.ini to make local testing easy

    To use:

    python -m pip install tox
    tox               # to test all versions
    tox -s            # --skip-missing-interpreters, if you don't have a version installed
    tox -e py310      # to test a single version
    tox -e py27,py310 # to test more than one
    tox -p auto       # run in parallel
    

    For example:

    image

    opened by hugovk 0
  • Include tests and useful/related test files in sdist

    Include tests and useful/related test files in sdist

    This is useful for downstream users, including OS packagers to QA/test if the package works correctly without requiring fetching the sources from the repository.

    Identified by: FreeBSD Ports Bug 242694

    Closes: #55

    opened by koobs 2
  • Include tests in PyPI tarball

    Include tests in PyPI tarball

    This is useful for downstream distributions to test if the package works correctly with their build recipe. Also, it provides a way to test if the dependencies as they are packaged by the distribution are compatible.

    opened by dotlambda 2
  • Include tests.py in pypi package

    Include tests.py in pypi package

    I'm in the process of adding httmock to the FreeBSD ports tree. One standard for most python port is to include tests.

    Looking at the httmock-1.2.6.tar.gz from https://pypi.python.org/pypi/httmock this tarball does not include tests.py.

    Would it be possible to include the tests.py file in the pypi package? If so I can add do-tests to the FreeBSD port.

    opened by derekschrock 0
Owner
Patryk Zawadzki
Head of Technology at Mirumee Software
Patryk Zawadzki
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 2k Jan 6, 2023
Hypothesis is a powerful, flexible, and easy to use library for property-based testing.

Hypothesis Hypothesis is a family of testing libraries which let you write tests parametrized by a source of examples. A Hypothesis implementation the

Hypothesis 6.4k Jan 1, 2023
Coroutine-based concurrency library for Python

gevent Read the documentation online at http://www.gevent.org. Post issues on the bug tracker, discuss and ask open ended questions on the mailing lis

gevent 5.9k Dec 28, 2022
A mocking library for requests

httmock A mocking library for requests for Python 2.7 and 3.4+. Installation pip install httmock Or, if you are a Gentoo user: emerge dev-python/httm

Patryk Zawadzki 452 Dec 28, 2022
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests >= 2.0 Installing p

Sentry 3.8k Jan 3, 2023
A mocking library for requests

httmock A mocking library for requests for Python 2.7 and 3.4+. Installation pip install httmock Or, if you are a Gentoo user: emerge dev-python/httm

Patryk Zawadzki 452 Dec 28, 2022
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests >= 2.0 Installing p

Sentry 3.8k Jan 2, 2023
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests >= 2.0 Installing p

Sentry 3.1k Feb 8, 2021
A mocking library for requests

httmock A mocking library for requests for Python 2.7 and 3.4+. Installation pip install httmock Or, if you are a Gentoo user: emerge dev-python/httm

Patryk Zawadzki 419 Feb 2, 2021
Asyncio http mocking. Similar to the responses library used for 'requests'

aresponses an asyncio testing server for mocking external services Features Fast mocks using actual network connections allows mocking some types of n

null 93 Nov 16, 2022
Multiple-requests-poster - A tool to send multiple requests to a particular website written in Python

Multiple-requests-poster - A tool to send multiple requests to a particular website written in Python

RLX 2 Feb 14, 2022
Library for mocking AsyncIOMotorClient built on top of mongomock.

mongomock-motor Best effort mock for AsyncIOMotorClient (Database, Collection, e.t.c) built on top of mongomock library. Example / Showcase from mongo

Michael Kryukov 43 Jan 4, 2023
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 2k Jan 6, 2023
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 2k Jan 6, 2023
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 1.9k Feb 6, 2021
Turn any OpenAPI2/3 and Postman Collection file into an API server with mocking, transformations and validations.

Prism is a set of packages for API mocking and contract testing with OpenAPI v2 (formerly known as Swagger) and OpenAPI v3.x. Mock Servers: Life-like

Stoplight 3.3k Jan 5, 2023
API mocking with Python.

apyr apyr (all lowercase) is a simple & easy to use mock API server. It's great for front-end development when your API is not ready, or when you are

Umut Seven 55 Nov 25, 2022
PyPasser is a Python library for bypassing reCaptchaV3 only by sending 2 requests.

PyPasser is a Python library for bypassing reCaptchaV3 only by sending 2 requests. In 1st request, gets token of captcha and in 2nd request,

null 253 Jan 5, 2023
Book search Django web project that uses requests python library and openlibrary API.

Book Search API Developer: Vladimir Vojtenko Book search Django web project that uses requests python library and openlibrary API. #requests #openlibr

null 1 Dec 8, 2021
EasyRequests is a minimalistic HTTP-Request Library that wraps aiohttp and asyncio in a small package that allows for sequential, parallel or even single requests

EasyRequests EasyRequests is a minimalistic HTTP-Request Library that wraps aiohttp and asyncio in a small package that allows for sequential, paralle

Avi 1 Jan 27, 2022