【发布时间】:2018-06-04 18:28:37
【问题描述】:
我正在尝试在我的 Flask 应用程序上测试一些调用外部 API 的路由,我想模拟这些路由。
路线是这样设置的:
@app.route('/url/<string::arg>')
def route_function(arg):
data = external_api(arg)
response = make_response(data)
# configure response
return response
我最初尝试过这样的事情:
class TestFlaskApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
@patch('external_api',
side_effect=mock_api)
def test_flask_route(self, api):
result = app.get('/url/arg')
self.assertEqual(result.status_code, 200)
api.assert_called_once_with('arg')
...失败了。未调用模拟 API 函数,因为我假设模拟不适用于应用程序上下文。
我也试过这个,认为我可以直接测试路由功能,从而避免使用应用上下文:
class TestAppFunctions(unittest.TestCase):
@patch('external_api',
side_effect=mock_api)
def test_flask_function(self, api):
result = my_flask_app.route_function('arg')
self.assertEqual(result.status_code, 200)
api.assert_called_once_with('arg')
...但这也不起作用,因为要做出响应,route_function 需要应用上下文。
那么有没有办法在应用上下文中进行模拟?在不触发外部 API 调用的情况下,我还能如何测试这些路由?
【问题讨论】:
-
您需要将对象路径传递给patch函数,以便在运行时解析并替换为mock。例如,如果在名为
routes的模块中调用external_api函数,该模块又包含在名为my_shining_app的包中,则将传递补丁my_shining_app.routes.external_api。我希望这可以解决这个问题。 -
在我的代码中,我有函数的完整路径(例如,
@patch('containingmodule.external_api'),但它仍然不起作用。模拟函数永远不会被调用。 -
请注意,路径应该是函数被调用的地方(即它被模拟替换的地方),而不是定义的地方。
标签: python-3.x unit-testing flask mocking