【问题标题】:How to mock an object returned by a mocked object?如何模拟被模拟对象返回的对象?
【发布时间】:2014-09-13 01:00:55
【问题描述】:

我不太了解 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() 方法正在尝试连接它们。

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    您想直接模拟 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_codecontent 设置为所需的值,最后将模拟响应分配给@987654326 @ 我们模拟的 post 函数。

    【讨论】:

    • 现在我看到了,这很有意义。它有效。谢谢你让我直截了当。 (FWIW,我在阅读的几个教程和快速入门中都找不到这个。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多