当请求对象被模拟时,如何测试代码的下一部分?

2024-04-25 02:16:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些Python函数是这样写的:

    def verify_secondary_hostnames(self, publishedName, hostnames):
        cname = self.get_cname(publishedName)
        edge_ip = requests.get('http://{}'.format(cname)).headers['X-Edge-IP']
        for hostname in hostnames:
            headers = {"host": hostname}
            data = requests.head("http://{}".format(edge_ip), headers=headers)
            data.raise_for_status()

我尝试为它编写的单元测试如下所示:

    @patch("requests.get")
    @patch("requests.head")
    @patch("FrontEnd.FrontEnd.get_cname")
    def test_verify_secondary_hostnames(self, mock_get_cname, mock_head, mock_get):
        mock_get_cname.return_value = "hulahoop"
        mock_get.return_value.headers = {"X-Edge-IP": "hulahoop"}
        self.fe.verify_secondary_hostnames('publishedName', ['hostname'])
        self.assertEqual(mock_head.call_args,
                         call('http://hulahoop', headers={'host': 'hostname'}))

在这个测试中,最后一部分raise_for_status实际上是这样做的:

def raise_for_status(self):
        """Raises stored :class:`HTTPError`, if one occurred."""

        http_error_msg = ''

        if 400 <= self.status_code < 500:
            http_error_msg = '%s Client Error: %s' % (self.status_code, self.reason)

        elif 500 <= self.status_code < 600:
            http_error_msg = '%s Server Error: %s' % (self.status_code, self.reason)

        if http_error_msg:
            raise HTTPError(http_error_msg, response=self)

我不能在这里做,因为我已经嘲笑了requests.head。我怎样才能写我的测试来弥补这一点呢?我这里所说的“cover”的意思是,既然对象是一个模拟对象,那么如何使它raise_for_status?我是否必须创建一个模拟方法来实现这一点,或者在测试中模拟加薪?你知道吗

编辑:这是我的最新测试,列出了以下问题:

@patch("requests.get")
@patch("requests.head")
@patch("FrontEnd.FrontEnd.get_cname")
@patch("requests.models.Response.raise_for_status")
def test_verify_secondary_hostnames(self, mock_raise,
                                    mock_get_cname, mock_head, mock_get):
    mock_get_cname.return_value = "hulahoop"
    mock_get.return_value.headers = {"X-Edge-IP": "hulahoop"}
    mock_head.return_value.status_code = 200
    self.fe.verify_secondary_hostnames('publishedName', ['hostname'])
    self.assertEqual(mock_head.call_args,
                     call('http://hulahoop', headers={'host': 'hostname'}))
    mock_head.raise_for_status.called <=== False here
    mock_head.reset_mock()
    mock_head.return_value.status_code = 400
    self.fe.verify_secondary_hostnames('publishedName', ['hostname'])
    mock_head.raise_for_status.called <=== Still false here.

Tags: selfhttpforgetstatusrequestsmockhead
1条回答
网友
1楼 · 发布于 2024-04-25 02:16:10

您可以在单元测试中尝试以下操作:

mock_data = mock.MagicMock()
mock_data.status_code = 200 # TODO (Low Kian Seong): Test raise_for_status
mock_head.return_value = mock_data
...

mock_data.raise_for_status.assert_called_once_with()

相关问题 更多 >