Python模拟没有获取属性

时间:2014-10-12 10:56:11

标签: python unit-testing mocking

我想测试的功能如下。我试图模仿此函数中的client,它来自我的auth模块。我试图让客户端的get函数返回一个Mock对象,该对象包含一个属性text,它引用我们的mock_response(进一步向下看)。

def get_person_by_email(email):
    client = auth.client()
    # print(client) = <Mock name='mock_client()' id='4324810640'>
    response = client.get(url="http://..." + email)
    # print(response) = <Mock name='mock_client().get()' id='4575780304'>
    # print(response.text) = <Mock name='mock_client().get().text' id='4348534608'>
    return jsonify(loads(utils.strip_security_string(response.text)))

抛出TypeError: 'Mock' object has no attribute '__getitem__'的函数是:

def strip_security_string(json_string):
    return "\n".join(json_string.split("\n")[1:])

这只是从响应中删除第一行。

最后,试图测试上述功能的代码:

def test_get_person_by_email():
    with app.test_client() as client:
        with app.app_context():
            mock_response = """security-string
                {"key":"value"}"""
            mock_client = Mock(name='mock_client')
            mock_client.get.return_value = Mock(text=mock_response)
            with patch.object(auth, 'client', mock_client):
                response = client.get("http://.../email/email@domain.com")

2 个答案:

答案 0 :(得分:4)

我不是模拟专家,但您可以尝试使用mock_client().get.return_value更改mock_client.get.return_value。这是因为代码使用auth.client()而不是auth.client

如果您不想访问模拟创建阶段中的mock_client(),您可以

mock_client_obj = Mock(name='mock_client_obj')
mock_client_obj.get.return_value = Mock(text=mock_response)
mock_client = Mock(name='mock_client',return_value=mock_client_obj)

或者更简单的

mock_client = Mock(name='mock_client')
mock_client.return_value.get.return_value.text = mock_response

答案 1 :(得分:0)

仔细看,mock_response未设置为有效的JSON值。也许你的意思是

mock_reponse= """[ "security-string", { "key": "value" } ]"""

有关描述正确值的语法,请参阅http://json.org