尝试修补或猴子修补Flask API中调用的函数时出现路径问题

时间:2018-12-12 20:30:33

标签: python unit-testing flask mocking pytest

我正在尝试为Flask应用程序构建一些测试,而我正努力使某些模拟/补丁工作按预期进行。

尽管花时间阅读/思考where to patch周围的文档,但@patchmonkeypatch均未达到我的预期,并且我正在努力查看自己在做错什么

在Flask api.py文件中,我有一个简单的登录API,用于检查身份验证要求(在其他位置定义并如图所示导入):

from project_name.api.auth import login_auth

@api.route('/v1/login', methods=['POST'])

    data = request.get_json()

    username = data['Username']
    password = data['Password']

    if not login_auth(username, password):
        raise APIError('Invalid Username or Password')
    ...

并且我有兴趣修补login_auth函数,以便在没有真实用户名/密码的情况下进行测试。

在pytest文件中,我尝试同时使用patch和Monkeypatch来解决此问题。

@patch方法:

@patch('project_name.api.auth.login_auth')
def test_login(mock_login_auth, client):
    mock_login_auth.return_value = True
    mimetype = 'application/json'
    headers = {
        'Content-Type': mimetype,
        'Accept': mimetype
    }
    data = {
        'Username': "test_user",
        'Password': "test_password",
    }
    url = 'api/v1/login'

    assert project_name.api.auth.login_auth('x', 'y') == True                                                                                                                                                                                                               

    response = client.post(url, data=json.dumps(data), headers=headers)
    assert response.status_code == 200

如果我运行此测试,则直接调用修补函数的第一个assert语句将按预期工作,但是API调用将不使用模拟的login_auth函数,并且该测试将失败此条件。

monkeypatch方法:

def test_login2(client, monkeypatch):
    monkeypatch.setattr("project_name.api.auth.login_auth", lambda x, y: True)
    mimetype = 'application/json'
    headers = {
        'Content-Type': mimetype,
        'Accept': mimetype
    }
    data = {
        'Username': "test_user",
        'Password': "test_password",
    }
    url = 'api/v1/login'

    assert project_name.api.auth.login_auth('x', 'y') == True                                                                                                                                                                                                               

    response = client.post(url, data=json.dumps(data), headers=headers)
    assert response.status_code == 200

再次,我看到第一个断言,该断言直接调用该函数,并按预期进行了修补,但是对API的请求之后正在调用的函数尚未进行修补,因此测试将在第二个{{ }}声明。

我尝试了许多不同的方法,包括尝试在路径assert上修补login_auth(假设我正在尝试修补导入到的特定login_auth函数) project_name.api.login_auth文件),但正确的方法对我来说还不清楚。

我想知道是否有需要做的特定事情,因为我正在使用Flask的test_client方法,或者是否还有其他我想念的东西。

1 个答案:

答案 0 :(得分:0)

这里的问题是在api.py中您正在导入模块的功能

from project_name.api.auth import login_auth

似乎需要匹配名称空间,因此,作为解决方法,您可以导入整个模块并使用完整的名称空间调用函数:

if not project_name.api.auth.login_auth(username, password):

您也可以看看另一个问题: mocking functions using python mock