You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试Mock lauApiSession API失败,求排查代码问题

单元测试Mock问题:如何避免真实网络连接

我负责的项目规模较大,尝试为lauApiSession编写单元测试,测试代码如下:

import unittest
from unittest.mock import patch, MagicMock
from alm_commons_utils.mylau.lau_client import lauApiSession


class TestlauApiSession(unittest.TestCase):
    @patch("alm_commons_utils.mylau.lau_client.lauApiSession.get_component")
    def test_mock_get_component(self, mock_get_component):
        # Mock the return value of get_component
        mock_get_component.return_value = {"component": "mock_component"}

        # Initialize the lauApiSession
        session = lauApiSession(
            ldap_user="mock_user",
            ldap_password="mock_password",
            lau_api_url="https://mock-lau-api-url",
            lau_login_url="https://mock-lau-login-url"
        )

        # Call the mocked method
        result = session.get_component("mock_repo")

        # Assert the mocked method was called with the correct arguments
        mock_get_component.assert_called_once_with("mock_repo")

        # Assert the return value is as expected
        self.assertEqual(result, {"component": "mock_component"})


if __name__ == "__main__":
    unittest.main()

在GitHub Action中执行该测试任务时,出现以下错误日志:

Run python -m unittest "alm_commons_utils.lautest.mock_lau_client" 
2025-06-03 10:58:33,011 - asyncio - DEBUG - Using selector: EpollSelector
2025-06-03 10:58:33,012 [INFO] Retrieving token from lau API... (alm_commons_utils.mylau.lau_client)
2025-06-03 10:58:33,012 - alm_commons_utils.mylau.lau_client - INFO - Retrieving token from lau API...
Error: -03 10:58:33,038 [ERROR] Error retrieving token: Cannot connect to host mock-lau-login-url:443 ssl:False [Name or service not known] (alm_commons_utils.mylau.lau_client)
2025-06-03 10:58:33,012 - root - INFO - Entry login_corporativo()
2025-06-03 10:58:33,012 - root - INFO - Entry on endpoint component_yaml_login_corporativo
2025-06-03 10:58:33,012 - root - DEBUG - Yaml alias is: mock_user
2025-06-03 10:58:33,012 - root - INFO - Exit on endpoint component_yaml_login_corporativo
2025-06-03 10:58:33,019 - root - ERROR - Timeout trying to make login
2025-06-03 10:58:33,022 - root - ERROR - Timeout trying to make login
2025-06-03 10:58:33,038 - alm_commons_utils.mylau.lau_client - ERROR - Error retrieving token: Cannot connect to host mock-lau-login-url:443 ssl:False [Name or service not known]

我希望测试完全Mock相关逻辑,不发起真实网络连接,请问我的代码存在什么问题?


问题分析

你只Mock了get_component方法,但**lauApiSession的初始化方法(__init__)内部会自动执行获取token的网络请求**,这部分逻辑没有被Mock,所以初始化session时会尝试连接目标地址,导致报错。

解决方案

需要额外Mock掉初始化时调用的token获取相关逻辑,根据lauApiSession的内部实现,有两种常见处理方式:

方式1:Mock内部的token获取方法

如果lauApiSession内部有专门处理token请求的方法(比如_get_token),直接Mock该方法返回假token:

import unittest
from unittest.mock import patch, MagicMock
from alm_commons_utils.mylau.lau_client import lauApiSession


class TestlauApiSession(unittest.TestCase):
    # 同时Mock get_component 和 内部token获取方法
    @patch("alm_commons_utils.mylau.lau_client.lauApiSession._get_token")
    @patch("alm_commons_utils.mylau.lau_client.lauApiSession.get_component")
    def test_mock_get_component(self, mock_get_component, mock_get_token):
        # Mock token返回值
        mock_get_token.return_value = "fake_auth_token"
        # Mock get_component返回值
        mock_get_component.return_value = {"component": "mock_component"}

        # 初始化session时,_get_token已被Mock,不会发起真实请求
        session = lauApiSession(
            ldap_user="mock_user",
            ldap_password="mock_password",
            lau_api_url="https://mock-lau-api-url",
            lau_login_url="https://mock-lau-login-url"
        )

        result = session.get_component("mock_repo")

        mock_get_component.assert_called_once_with("mock_repo")
        self.assertEqual(result, {"component": "mock_component"})


if __name__ == "__main__":
    unittest.main()

方式2:Mock底层请求库

如果lauApiSession是通过第三方请求库(比如requests)发起token请求,直接Mock对应的请求方法:

import unittest
from unittest.mock import patch, MagicMock
from alm_commons_utils.mylau.lau_client import lauApiSession


class TestlauApiSession(unittest.TestCase):
    # Mock requests.post和get_component方法
    @patch("alm_commons_utils.mylau.lau_client.requests.post")
    @patch("alm_commons_utils.mylau.lau_client.lauApiSession.get_component")
    def test_mock_get_component(self, mock_get_component, mock_post):
        # 构造Mock响应对象
        mock_response = MagicMock()
        mock_response.json.return_value = {"token": "fake_auth_token"}
        mock_response.status_code = 200
        mock_post.return_value = mock_response

        # Mock get_component返回值
        mock_get_component.return_value = {"component": "mock_component"}

        # 初始化session,不会触发真实请求
        session = lauApiSession(
            ldap_user="mock_user",
            ldap_password="mock_password",
            lau_api_url="https://mock-lau-api-url",
            lau_login_url="https://mock-lau-login-url"
        )

        result = session.get_component("mock_repo")

        mock_get_component.assert_called_once_with("mock_repo")
        self.assertEqual(result, {"component": "mock_component"})


if __name__ == "__main__":
    unittest.main()

核心思路是找到lauApiSession初始化时触发网络请求的根源,把对应的依赖Mock掉,确保整个测试流程没有真实的网络调用。

内容的提问来源于stack exchange,提问作者MJoao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:17:03