@@ -139,13 +139,20 @@ def test_get_mcp_endpoint_no_name(self):
139139 endpoint = tool ._get_mcp_endpoint ()
140140 assert endpoint is None
141141
142- def test_get_mcp_endpoint_no_data_endpoint (self ):
143- """测试没有 data_endpoint 时获取 MCP endpoint"""
142+ @patch ("agentrun.tool.tool.Config" )
143+ def test_get_mcp_endpoint_no_data_endpoint (self , mock_config_class ):
144+ """测试没有 data_endpoint 时从 Config.get_data_endpoint() 兜底"""
145+ mock_config = Mock ()
146+ mock_config .get_data_endpoint .return_value = (
147+ "https://fallback.example.com"
148+ )
149+ mock_config_class .with_configs .return_value = mock_config
150+
144151 tool = Tool (
145152 tool_name = "my-tool" ,
146153 )
147154 endpoint = tool ._get_mcp_endpoint ()
148- assert endpoint is None
155+ assert endpoint == "https://fallback.example.com/tools/my-tool/sse"
149156
150157 def test_from_inner_object (self ):
151158 """测试从内部对象创建 Tool"""
@@ -244,8 +251,11 @@ def test_list_tools_mcp(self, mock_config_class, mock_mcp_session_class):
244251 assert tools [0 ].name == "tool1"
245252 assert tools [1 ].name == "tool2"
246253
254+ @patch ("agentrun.tool.tool.Config" )
247255 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
248- def test_list_tools_functioncall (self , mock_openapi_client_class ):
256+ def test_list_tools_functioncall (
257+ self , mock_openapi_client_class , mock_config_class
258+ ):
249259 """测试获取 FUNCTIONCALL 工具列表"""
250260 mock_client = Mock ()
251261 mock_client .list_tools .return_value = [
@@ -254,6 +264,13 @@ def test_list_tools_functioncall(self, mock_openapi_client_class):
254264 ]
255265 mock_openapi_client_class .return_value = mock_client
256266
267+ mock_config = Mock ()
268+ mock_config .get_data_endpoint .return_value = (
269+ "https://fallback.example.com"
270+ )
271+ mock_config .get_headers .return_value = {}
272+ mock_config_class .with_configs .return_value = mock_config
273+
257274 tool = Tool (
258275 tool_type = "FUNCTIONCALL" ,
259276 protocol_spec = '{"openapi": "3.0.0"}' ,
@@ -295,7 +312,7 @@ def test_call_tool_mcp(self, mock_config_class, mock_mcp_session_class):
295312 assert result == {"result" : "success" }
296313
297314 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
298- @patch ("agentrun.utils.config .Config" )
315+ @patch ("agentrun.tool.tool .Config" )
299316 def test_call_tool_functioncall (
300317 self , mock_config_class , mock_openapi_client_class
301318 ):
@@ -306,6 +323,11 @@ def test_call_tool_functioncall(
306323
307324 mock_config = Mock ()
308325 mock_config .get_headers .return_value = {}
326+ mock_config .get_data_endpoint .return_value = (
327+ "https://fallback.example.com"
328+ )
329+ mock_config .get_access_key_id .return_value = ""
330+ mock_config .get_access_key_secret .return_value = ""
309331 mock_config_class .with_configs .return_value = mock_config
310332
311333 tool = Tool (
@@ -417,9 +439,11 @@ def test_get_skill_download_url_tool_name_takes_priority(self):
417439
418440 @patch ("agentrun.tool.tool.Config" )
419441 def test_get_skill_download_url_config_fallback (self , mock_config_class ):
420- """测试 data_endpoint 为空时从 Config 获取"""
442+ """测试 data_endpoint 为空时从 Config.get_data_endpoint() 获取"""
421443 mock_config = Mock ()
422- mock_config ._data_endpoint = "https://config-endpoint.com"
444+ mock_config .get_data_endpoint .return_value = (
445+ "https://config-endpoint.com"
446+ )
423447 mock_config_class .with_configs .return_value = mock_config
424448
425449 tool = Tool (tool_name = "my-skill" )
@@ -434,9 +458,9 @@ def test_get_skill_download_url_no_name(self):
434458
435459 @patch ("agentrun.tool.tool.Config" )
436460 def test_get_skill_download_url_no_endpoint (self , mock_config_class ):
437- """测试没有 data_endpoint 且 Config 也没有时返回 None"""
461+ """测试没有 data_endpoint 且 Config.get_data_endpoint() 返回空时返回 None"""
438462 mock_config = Mock ()
439- mock_config ._data_endpoint = None
463+ mock_config .get_data_endpoint . return_value = ""
440464 mock_config_class .with_configs .return_value = mock_config
441465
442466 tool = Tool (tool_name = "my-skill" )
@@ -558,8 +582,13 @@ async def test_download_skill_async_wrong_type(self):
558582 with pytest .raises (ValueError , match = "only available for SKILL" ):
559583 await tool .download_skill_async ()
560584
561- async def test_download_skill_async_no_url (self ):
562- """测试无法构造下载 URL 时抛出 ValueError"""
585+ @patch ("agentrun.tool.tool.Config" )
586+ async def test_download_skill_async_no_url (self , mock_config_class ):
587+ """测试无法构造下载 URL 时抛出 ValueError(无 name 且 get_data_endpoint 返回空)"""
588+ mock_config = Mock ()
589+ mock_config .get_data_endpoint .return_value = ""
590+ mock_config_class .with_configs .return_value = mock_config
591+
563592 tool = Tool (tool_type = "SKILL" )
564593
565594 with pytest .raises (ValueError , match = "Cannot construct download URL" ):
@@ -875,7 +904,7 @@ def test_call_tool_mcp_bundle_always_uses_ram(
875904 assert call_kwargs ["use_ram_auth" ] is True
876905
877906 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
878- @patch ("agentrun.utils.config .Config" )
907+ @patch ("agentrun.tool.tool .Config" )
879908 def test_call_tool_functioncall_openapi_import_skips_ram (
880909 self , mock_config_class , mock_openapi_client_class
881910 ):
@@ -886,6 +915,11 @@ def test_call_tool_functioncall_openapi_import_skips_ram(
886915
887916 mock_config = Mock ()
888917 mock_config .get_headers .return_value = {}
918+ mock_config .get_data_endpoint .return_value = (
919+ "https://fallback.example.com"
920+ )
921+ mock_config .get_access_key_id .return_value = ""
922+ mock_config .get_access_key_secret .return_value = ""
889923 mock_config_class .with_configs .return_value = mock_config
890924
891925 tool = Tool (
@@ -961,7 +995,7 @@ async def test_call_tool_async_mcp_remote_without_proxy_skips_ram(
961995 assert call_kwargs ["use_ram_auth" ] is False
962996
963997 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
964- @patch ("agentrun.utils.config .Config" )
998+ @patch ("agentrun.tool.tool .Config" )
965999 async def test_call_tool_async_functioncall_openapi_import_skips_ram (
9661000 self , mock_config_class , mock_openapi_client_class
9671001 ):
@@ -972,6 +1006,11 @@ async def test_call_tool_async_functioncall_openapi_import_skips_ram(
9721006
9731007 mock_config = Mock ()
9741008 mock_config .get_headers .return_value = {}
1009+ mock_config .get_data_endpoint .return_value = (
1010+ "https://fallback.example.com"
1011+ )
1012+ mock_config .get_access_key_id .return_value = ""
1013+ mock_config .get_access_key_secret .return_value = ""
9751014 mock_config_class .with_configs .return_value = mock_config
9761015
9771016 tool = Tool (
@@ -1244,25 +1283,37 @@ def test_get_functioncall_server_url(self):
12441283
12451284 assert url == "https://example.com/data/tools/my-tool"
12461285
1247- def test_get_functioncall_server_url_no_endpoint (self ):
1286+ @patch ("agentrun.tool.tool.Config" )
1287+ def test_get_functioncall_server_url_no_endpoint (self , mock_config_class ):
12481288 """测试 _get_functioncall_server_url 没有 data_endpoint 和 name 时返回 None"""
1289+ mock_config = Mock ()
1290+ mock_config .get_data_endpoint .return_value = (
1291+ "https://fallback.example.com"
1292+ )
1293+ mock_config_class .with_configs .return_value = mock_config
1294+
12491295 tool = Tool ()
12501296 url = tool ._get_functioncall_server_url ()
12511297
12521298 assert url is None
12531299
1254- @patch ("agentrun.utils.config .Config" )
1300+ @patch ("agentrun.tool.tool .Config" )
12551301 async def test_list_tools_async_mcp_no_endpoint (self , mock_config_class ):
1256- """测试 MCP 类型但没有 endpoint 时返回空列表"""
1302+ """测试 MCP 类型但没有 endpoint 时,使用 Config.get_data_endpoint() 兜底"""
1303+ mock_config = Mock ()
1304+ mock_config .get_data_endpoint .return_value = ""
1305+ mock_config_class .with_configs .return_value = mock_config
1306+
12571307 tool = Tool (tool_name = "my-tool" , tool_type = "MCP" )
12581308
12591309 tools = await tool .list_tools_async ()
12601310
12611311 assert tools == []
12621312
1313+ @patch ("agentrun.tool.tool.Config" )
12631314 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
12641315 async def test_list_tools_async_functioncall (
1265- self , mock_openapi_client_class
1316+ self , mock_openapi_client_class , mock_config_class
12661317 ):
12671318 """测试 FUNCTIONCALL 类型的 list_tools_async"""
12681319 mock_client = Mock ()
@@ -1274,6 +1325,13 @@ async def test_list_tools_async_functioncall(
12741325 )
12751326 mock_openapi_client_class .return_value = mock_client
12761327
1328+ mock_config = Mock ()
1329+ mock_config .get_data_endpoint .return_value = (
1330+ "https://fallback.example.com"
1331+ )
1332+ mock_config .get_headers .return_value = {}
1333+ mock_config_class .with_configs .return_value = mock_config
1334+
12771335 tool = Tool (
12781336 tool_type = "FUNCTIONCALL" ,
12791337 protocol_spec = '{"openapi": "3.0.0"}' ,
@@ -1292,7 +1350,7 @@ async def test_list_tools_async_no_type(self):
12921350 assert tools == []
12931351
12941352 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
1295- @patch ("agentrun.utils.config .Config" )
1353+ @patch ("agentrun.tool.tool .Config" )
12961354 async def test_call_tool_async_functioncall (
12971355 self , mock_config_class , mock_openapi_client_class
12981356 ):
@@ -1305,6 +1363,11 @@ async def test_call_tool_async_functioncall(
13051363
13061364 mock_config = Mock ()
13071365 mock_config .get_headers .return_value = {}
1366+ mock_config .get_data_endpoint .return_value = (
1367+ "https://fallback.example.com"
1368+ )
1369+ mock_config .get_access_key_id .return_value = ""
1370+ mock_config .get_access_key_secret .return_value = ""
13081371 mock_config_class .with_configs .return_value = mock_config
13091372
13101373 tool = Tool (
@@ -1316,15 +1379,20 @@ async def test_call_tool_async_functioncall(
13161379
13171380 assert result == {"result" : "success" }
13181381
1319- async def test_call_tool_async_mcp_no_endpoint (self ):
1382+ @patch ("agentrun.tool.tool.Config" )
1383+ async def test_call_tool_async_mcp_no_endpoint (self , mock_config_class ):
13201384 """测试 MCP 类型但没有 endpoint 时 call_tool_async 抛出 ValueError"""
1385+ mock_config = Mock ()
1386+ mock_config .get_data_endpoint .return_value = ""
1387+ mock_config_class .with_configs .return_value = mock_config
1388+
13211389 tool = Tool (tool_name = "my-tool" , tool_type = "MCP" )
13221390
13231391 with pytest .raises (ValueError , match = "MCP endpoint not available" ):
13241392 await tool .call_tool_async ("tool1" , {"param" : "value" })
13251393
13261394 @patch ("agentrun.tool.api.openapi.ToolOpenAPIClient" )
1327- @patch ("agentrun.utils.config .Config" )
1395+ @patch ("agentrun.tool.tool .Config" )
13281396 def test_call_tool_functioncall (
13291397 self , mock_config_class , mock_openapi_client_class
13301398 ):
@@ -1335,6 +1403,11 @@ def test_call_tool_functioncall(
13351403
13361404 mock_config = Mock ()
13371405 mock_config .get_headers .return_value = {}
1406+ mock_config .get_data_endpoint .return_value = (
1407+ "https://fallback.example.com"
1408+ )
1409+ mock_config .get_access_key_id .return_value = ""
1410+ mock_config .get_access_key_secret .return_value = ""
13381411 mock_config_class .with_configs .return_value = mock_config
13391412
13401413 tool = Tool (
@@ -1346,16 +1419,25 @@ def test_call_tool_functioncall(
13461419
13471420 assert result == {"result" : "success" }
13481421
1349- def test_call_tool_mcp_no_endpoint (self ):
1422+ @patch ("agentrun.tool.tool.Config" )
1423+ def test_call_tool_mcp_no_endpoint (self , mock_config_class ):
13501424 """测试 MCP 类型但没有 endpoint 时 call_tool 抛出 ValueError"""
1425+ mock_config = Mock ()
1426+ mock_config .get_data_endpoint .return_value = ""
1427+ mock_config_class .with_configs .return_value = mock_config
1428+
13511429 tool = Tool (tool_name = "my-tool" , tool_type = "MCP" )
13521430
13531431 with pytest .raises (ValueError , match = "MCP endpoint not available" ):
13541432 tool .call_tool ("tool1" , {"param" : "value" })
13551433
1356- @patch ("agentrun.utils.config .Config" )
1434+ @patch ("agentrun.tool.tool .Config" )
13571435 def test_list_tools_mcp_no_endpoint (self , mock_config_class ):
13581436 """测试 MCP 类型但没有 endpoint 时 list_tools 返回空列表"""
1437+ mock_config = Mock ()
1438+ mock_config .get_data_endpoint .return_value = ""
1439+ mock_config_class .with_configs .return_value = mock_config
1440+
13591441 tool = Tool (tool_name = "my-tool" , tool_type = "MCP" )
13601442
13611443 tools = tool .list_tools ()
0 commit comments