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
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
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
Wraps any WSGI application and makes it easy to send test requests to that application, without starting up an HTTP server.

WebTest This wraps any WSGI application and makes it easy to send test requests to that application, without starting up an HTTP server. This provides

Pylons Project 325 Dec 30, 2022
Aioresponses is a helper for mock/fake web requests in python aiohttp package.

aioresponses Aioresponses is a helper to mock/fake web requests in python aiohttp package. For requests module there are a lot of packages that help u

null 402 Jan 6, 2023
Integration layer between Requests and Selenium for automation of web actions.

Requestium is a Python library that merges the power of Requests, Selenium, and Parsel into a single integrated tool for automatizing web actions. The

Tryolabs 1.7k Dec 27, 2022
ApiPy was created for api testing with Python pytest framework which has also requests, assertpy and pytest-html-reporter libraries.

ApiPy was created for api testing with Python pytest framework which has also requests, assertpy and pytest-html-reporter libraries. With this f

Mustafa 1 Jul 11, 2022
API Test Automation with Requests and Pytest

api-testing-requests-pytest Install Make sure you have Python 3 installed on your machine. Then: 1.Install pipenv sudo apt-get install pipenv 2.Go to

Sulaiman Haque 2 Nov 21, 2021
A Python Selenium library inspired by the Testing Library

Selenium Testing Library Slenium Testing Library (STL) is a Python library for Selenium inspired by Testing-Library. Dependencies Python 3.6, 3.7, 3.8

Anže Pečar 12 Dec 26, 2022
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 5, 2023
Headless chrome/chromium automation library (unofficial port of puppeteer)

Pyppeteer Pyppeteer has moved to pyppeteer/pyppeteer Unofficial Python port of puppeteer JavaScript (headless) chrome/chromium browser automation libr

miyakogi 3.5k Dec 30, 2022
Web testing library for Robot Framework

SeleniumLibrary Contents Introduction Keyword Documentation Installation Browser drivers Usage Extending SeleniumLibrary Community Versions History In

Robot Framework 1.2k Jan 3, 2023
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

null 909 Dec 15, 2022
Selenium-python but lighter: Helium is the best Python library for web automation.

Selenium-python but lighter: Helium Selenium-python is great for web automation. Helium makes it easier to use. For example: Under the hood, Helium fo

Michael Herrmann 3.2k Dec 31, 2022
A framework-agnostic library for testing ASGI web applications

async-asgi-testclient Async ASGI TestClient is a library for testing web applications that implements ASGI specification (version 2 and 3). The motiva

null 122 Nov 22, 2022