The implement of responses for mocking out the requests

The implement of responses for mocking out the requests


Utility of responses

Basic
import responses
import requests

responses.add(responses.GET,'http://twitter.com/api/1/foobar', 
              json={'error': 'not found'}, status=404)

@responses.activate
def test_sample():

    resp = requests.get('http://twitter.com/api/1/foobar')

    assert resp.json() == {"error": "not found"}
    assert resp.status_code = 404

... '''
Multiple responses
import responses
import requests

responses.add(responses.GET,'http://twitter.com/api/1/foobar', 
              status=500)
responses.add(responses.GET,'http://twitter.com/api/1/foobar', 
              body='{}', status=200, 
              content_type='application/json')

@responses.activate
def test_multiple():
    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.status_code == 500
    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.status_code == 200

... '''
Using a callback to modify the response
import responses
import requests

def response_callback(resp):
    resp.callback_processed = True
    return resp

with responses.RequestsMock(response_callback=response_callback) as m:
    m.add(responses.GET, 'http://example.com', body=b'test')
    resp = requests.get('http://example.com')
    assert resp.text == "test"
    assert hasattr(resp, 'callback_processed')
    assert resp.callback_processed is True

... '''

Structure of responses

RequestMock
方法作用
_ init _初始化
reset重置
add添加response
add_passthru
remove
replace
add_callback
calls
_ enter _启动mock
_ exit _恢复
activatewrap testcase()
_find_matchget response
_on_requestreturn response
start启动mock
stop恢复
BaseResponse
方法作用
_ init _初始化
_ eq _
_ ne _
_url_matches_strict
_url_matchesurl -> response
get_header
get_response
matches
Response
方法作用
_ init _初始化
get_response
CallbackResponse
方法作用
_ init _初始化
get_response
Module方法
方法作用
_is_string
_has_unicode
_clean_unicode
_is_redirect
get_wrapped包装testcase()
_ensure_url_default_path
_handle_body

How it works

wrap test_example():
Created with Raphaël 2.1.2 test_example() responses.activate(RequestMock.activate()) get_wrapped() wrapped_test_example()
execute wrapped_test_example():
Created with Raphaël 2.1.2 wrapped_test_example() RequestMock.__enter__() RequestMock.start() mock.patch() requests.adapters.HTTPAdapter.send,unbound_on_send() test_example() _on_request() get_response() Response
get_wrapped():
import inspect
import six

from functools import update_wrapper

_wrapper_template = """\
def wrapper%(signature)s:
    with responses:
        return func%(funcargs)s
"""

def get_wrapped(func, wrapper_template, evaldict):
    if six.PY2:
        args, a, kw, defaults = inspect.getargspec(func)
    else:
        args, a, kw, defaults, kwonlyargs, kwonlydefaults, 
        annotations = inspect.getfullargspec(func)

    signature = inspect.formatargspec(args, a, kw, defaults)
    is_bound_method = hasattr(func, '__self__')
    if is_bound_method:
        args = args[1:]  # Omit 'self'
    callargs = inspect.formatargspec(args, a, kw, None)

    ctx = {'signature': signature, 'funcargs': callargs}
    six.exec_(wrapper_template % ctx, evaldict)

    wrapper = evaldict['wrapper']

    update_wrapper(wrapper, func)
    if is_bound_method:
        wrapper = wrapper.__get__(func.__self__, 
        type(func.__self__))
return wrapper
... '''
RequestMock.start()
def start(self):
        try:
            from unittest import mock
        except ImportError:
            import mock

        def unbound_on_send(adapter, request, *a, **kwargs):
            return self._on_request(adapter, request, *a, 
                                    **kwargs)

        self._patcher = mock.patch(
            'requests.adapters.HTTPAdapter.send', 
             unbound_on_send)
        self._patcher.start()
... '''

wrapped_test_example()

def wrapper%(args_signature)s:
    with responses:
        return test_example%(funcargs)s
... '''

延伸

  • 支持更多HTTP请求框架 :urllib,httplib,aiohttp;
  • 支持ORM :SQLAlchemy,peewee。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值