我不太熟悉Python嘲笑。
显然,我不希望我的测试代码在以下方法中调用实际方法requests.post()
,所以我想改为模仿其行为:
def try_post(self, url, body):
r = requests.post(url, data=body)
msg = str(r.status_code) + " " + r.content + "\n"
if r.status_code >= 300:
sys.stderr.write("Error: POST returned " + msg)
我的问题:如何模拟requests.post()
返回的对象,即响应对象?
例如,我想写一个测试,其中r.status_code是200,另一个是r.status_code是300,所以我可以测试条件逻辑。另外,我需要模拟r.content来返回一些字符串。
我的非工作代码如下:
from monitor_writer import MonitorWriter
import mock
import unittest
class TestMonitorWriter(unittest.TestCase):
@mock.patch('monitor_writer.requests')
def test_conforming_write(self, mock_requests):
xml_frag = """
<InstantaneousDemand>
</InstantaneousDemand>
"""
mock_requests.status_code.return_value = 200
mock_requests.content.return_value = "OK"
writer = MonitorWriter()
writer.update(xml_frag)
self.assertTrue(mock_requests.post.called, "Failed to call requests.post")
此测试因TypeError: expected a character buffer object
而失败,因为r.status_code和r.content评估为mock.MagicMock对象,而不是字符串,而try_post()方法正在尝试连接它们。
答案 0 :(得分:2)
您想直接模拟requests.post
,而不是整个requests
模块:
class TestMonitorWriter(unittest.TestCase):
@mock.patch('monitor_writer.requests.post')
def test_conforming_write(self, mock_post):
xml_frag = """
<InstantaneousDemand>
</InstantaneousDemand>
"""
response = mock.MagicMock()
response.status_code = 200
respone.content = "OK"
mock_post.return_value = response
writer = MonitorWriter()
writer.update(xml_frag)
self.assertTrue(mock_post.called, "Failed to call requests.post")
一旦我们嘲笑了您实际调用的函数,我们就会创建一个模拟响应对象,在模拟的响应中设置status_code
和content
,最后将模拟的响应分配给我们的模拟return_value
函数的post
。