Python模拟requests.post抛出异常

时间:2018-02-10 17:42:35

标签: python unit-testing mocking python-requests

使用Python 3.5,请求== 2.18.4,Flask == 0.12.2,urllib3 == 1.22

我的主some_method文件中有一个方法server.py,该方法可能会为某个网址提供POST一些数据:

def some_method(url, data):
    ...
    error = None
    try:
        response = requests.post(url, json=data)
    except requests.exceptions.ConnectionError as e:
        ...
        app.logger.error(...)
        response = None
        error = str(e)
    return error, response

服务器文件定义:app = Flask(__name__)some_method调用@app.route(... methods=['PATCH'])
如果此方法抛出错误,则路由最终将返回500

测试是通过使用import serverapp = server.app导入应用的测试文件,使用unittest和导入mock.patch来运行的。

我能够测试整体应用行为,测试显示当方法返回错误并看到路由终止于正确的位置时,应用路由按预期运行:

class ServerTestCase(unittest.TestCase):
    ...
    @patch('server.some_method')
    def test_route_response_status_500_when_throws(self, mock_response):
        mock_response.return_value = 'some_error_string', None
        response = self.app.patch(some_url, some_data, content_type='application/json')
        self.assertEqual(response.status_code, 500)

但是,我真的希望有另一个测试来单独测试some_method

  1. 模拟requests.post投掷requests.exceptions.ConnectionError
  2. 显示该方法记录错误(我知道我可以模拟我的app.logger并声明它在执行期间记录了)

1 个答案:

答案 0 :(得分:4)

模拟requests.post函数,并在模拟上将side_effect attribute设置为所需的异常:

@patch('requests.post')
def test_request_post_exception(self, post_mock):
    post_mock.side_effect = requests.exceptions.ConnectionError()
    # run your test, code calling `requests.post()` will trigger the exception.

来自链接文档:

  

这可以是调用mock时要调用的函数,要引发的可迭代或异常(类或实例)。

     

[...]

     

引发异常的模拟示例(用于测试API的异常处理):

>>> mock = Mock()
>>> mock.side_effect = Exception('Boom!')
>>> mock()
Traceback (most recent call last):
  ...
Exception: Boom!

(大胆强调我的)。

Quick Guide section

也涵盖了这一点
  

side_effect允许您执行副作用,包括在调用模拟时引发异常:

>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
 ...
KeyError: 'foo'