我可以在测试Flask app功能时使用模拟吗?

时间:2018-06-04 18:28:38

标签: python-3.x unit-testing flask mocking

我正在尝试在我的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调用的情况下测试这些路由呢?

1 个答案:

答案 0 :(得分:1)

Oluwafemi Sule是正确的……我只需要在使用该功能的地方而不是在定义该位置的地方打补丁。

  

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

传递      

请注意,路径应位于调用函数的位置(即将其替换为模拟对象的位置),而不是定义位置