【问题标题】:Can I use mocks in testing Flask app functions?我可以在测试 Flask 应用程序功能时使用模拟吗?
【发布时间】: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


【解决方案1】:

Oluwafemi Sule 是对的...我只需要在使用它的地方修补函数,而不是在它定义的地方。

您需要将对象路径传递给补丁函数,以便它可以在运行时解析并替换为模拟。例如,如果在名为routes 的模块中调用external_api function,而该模块又包含在名为my_shining_app 的包中,则patch 将作为my_shining_app.routes.external_api 传递

请注意,路径应该是函数被调用的地方(即它被模拟替换的地方),而不是它被定义的地方

【讨论】:

  • 一个要清楚的例子,因为我必须阅读两次才能正确理解:假设您已将 myfuncmymodule.py 导入到 main.py。您必须使用 utnittest 修补 main.myfunc 才能使其正常工作。不是mymodule.myfunc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多