如何为 python 的 requests.Response.text 属性设置值?

Posted

技术标签:

【中文标题】如何为 python 的 requests.Response.text 属性设置值?【英文标题】:How to set value to python's requests.Response.text property? 【发布时间】:2019-01-30 17:31:12 【问题描述】:

我想在我的单元测试中模拟 requests.Response() 对象,我从下面的链接中得到了提示。

How to mock data as request.Response type in python

在这里,我可以只设置status_code 的值(不是@Property),我想设置@Property 的值textcontent

类用户名密码AuthStrategyTest(TestCase):

def test_do_success(self):
    content = self._factory.get_reader(ReaderType.CONTENT).read('MY_TEST')
    auth_strategy = UsernamePasswordAuthStrategy(content)
    # mock send_request method response
    response = Response()
    response.status_code = 200
    # How could I achieve below line? 
    response.text = """<html>
            <body>
                <form method="post" name="NavForm">
                    <input id="csrfKey" name="csrfKey" type="hidden" value="JEK7schtDx5IVcH1eOWKN9lFH7ptcwHD/"/>
                </form>
            </body>
        </html>"""
    auth_strategy.send_request = mock.MagicMock(return_value=response)
    session, auth_result = auth_strategy.do()  # 'for_next_url_params': 'csrfKey': 'T4WNcz+hXqrxVa5R9o2HXkDm8pNZEi4k/'
    self.assertTrue(session, 'Test Failed! Something went wrong')
    self.assertTrue('for_next_url_params' in auth_result and 'csrfKey' in auth_result['for_next_url_params'],
                    'Test Failed! csrfKey not found')

send_request 返回response

【问题讨论】:

我们需要你的一些代码来解决问题。 @eagle33322 提供的链接有足够的信息,所以之前没有添加代码。您也可以在提供的链接中举一个例子 How to mock data as request.Response type in python的可能重复 @eagle33322 不是真的,该示例只是说明如何为status_code 设置值而不是@Property 以及我在描述中使用的相同链接 【参考方案1】:

我已经浏览了python文档并弄清楚了......

解决方案是->

def test_do_success(self):
        content = self._factory.get_reader(ReaderType.CONTENT).read('MY_TEST')
        auth_strategy = UsernamePasswordAuthStrategy(content)
        # mock send_request method response
        response = Response()
        response.status_code = 200
        my_text = """<html>
                <body>
                    <form method="post" name="NavForm">
                        <input id="csrfKey" name="csrfKey" type="hidden" value="JEK7schtDx5IVcH1eOWKN9lFH7ptcwHD/"/>
                    </form>
                </body>
            </html>
        """
        type(response).text = mock.PropertyMock(return_value=my_text)
        auth_strategy.send_request = mock.MagicMock(return_value=response)
        session, auth_result = auth_strategy.do()
        self.assertTrue(session, 'Test Failed! Something went wrong')
        self.assertTrue('JEK7schtDx5IVcH1eOWKN9lFH7ptcwHD' in auth_result['for_next_url_params']['csrfKey'],
                        'Test Failed! csrfKey not found')

我在文本周围添加了PropertyMock,代码更改是-->

type(response).text = mock.PropertyMock(return_value=my_text)

【讨论】:

不错的答案。我想知道它是如何/为什么起作用的;您能否将其添加到您的答案或您提到的文档的链接中? 此解决方案为requests.Response 类重新定义text 属性。可以通过以下方式检查:import requests as r; a = r.request('POST', 'https://www.google.com'); type(a).text = '"k":"v"'; a = r.request('POST', 'https://www.google.com'); print(a.text)。即使在 a 将被重新分配之后,在重新启动过程之前,文本将始终为 '"k":"v"'【参考方案2】:

text的值可以通过使用私有属性_content来设置(应该是bytes):

import requests as r

res = r.Response()
res.status_code = 404

utf_string = '"error": "page not found", "check UTF8 characters": "あア"'
bytes_string = utf_string.encode('utf-8')
res._content = bytes_string

print('Status code:', res.status_code)
print('RAW:', f'[type(res.content)]', res.content)
print('Private RAW:', f'[type(res._content)]', res._content)
print('Decoded text:', f'[type(res.text)]', res.text)
print('JSON converted:', f'[type(res.json())]', res.json())

输出:

Status code: 404
RAW: [<class 'bytes'>] b'"error": "page not found", "check UTF8 characters": "\xe3\x81\x82\xe3\x82\xa2"'
Private RAW: [<class 'bytes'>] b'"error": "page not found", "check UTF8 characters": "\xe3\x81\x82\xe3\x82\xa2"'
Decoded text: [<class 'str'>] "error": "page not found", "check UTF8 characters": "あア"
JSON converted: [<class 'dict'>] 'error': 'page not found', 'check UTF8 characters': 'あア'

【讨论】:

这是一个非常有用的答案。我认为它实际上优于公认的答案,因为它看起来更简单。您可能会考虑突出显示的一条关键信息(因为它在代码视图中滚动离开页面)是第 4 代码行上的 .encode('utf-8')。也许将字符串分配给不同行上的变量,然后将 _content 分配给该变量。然后编码调用将更加明显。只是一个想法。我第一次看你的答案时错过了。 这是手动将预加载的.text 推送到响应以进行内部测试的一种快速而肮脏的方法,而不是加载完整的 API 调用并等待 5 分钟让您的服务器下载数据。

以上是关于如何为 python 的 requests.Response.text 属性设置值?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Python 制作 C++ 库

python:如何为字母赋值?

如何为 python 2.7 安装 psycopg2

如何为 Python 配置 arduino ide?

如何为 Alpine 编译 python?

如何为 Python 安装 OpenSSL