""" 环境变量加载器测试 """ import os import tempfile from pathlib import Path from unittest.mock import patch import pytest from neobot.core.utils.env_loader import EnvLoader class TestEnvLoader: """环境变量加载器测试类""" def test_init_with_default_env_file(self): """测试使用默认 .env 文件初始化""" loader = EnvLoader() assert loader.env_file == Path(".env") assert not loader._loaded def test_init_with_custom_env_file(self): """测试使用自定义 .env 文件初始化""" loader = EnvLoader("custom.env") assert loader.env_file == Path("custom.env") def test_load_env_file_exists(self): """测试加载存在的 .env 文件""" with tempfile.NamedTemporaryFile(mode='w', suffix='.env', delete=False) as f: f.write("UNIQUE_TEST_KEY=test_value\nUNIQUE_ANOTHER_KEY=another_value") env_file = f.name try: loader = EnvLoader(env_file) loader.load() assert loader._loaded assert loader.get("UNIQUE_TEST_KEY") == "test_value" assert loader.get("UNIQUE_ANOTHER_KEY") == "another_value" finally: os.unlink(env_file) def test_load_env_file_not_exists(self): """测试加载不存在的 .env 文件""" loader = EnvLoader("non_existent.env") loader.load() # 应该仍然加载成功,只是没有文件 assert loader._loaded def test_get_existing_key(self): """测试获取存在的环境变量""" with patch.dict(os.environ, {"EXISTING_KEY": "existing_value"}): loader = EnvLoader() loader.load() value = loader.get("EXISTING_KEY") assert value == "existing_value" def test_get_non_existing_key_with_default(self): """测试获取不存在的环境变量(带默认值)""" loader = EnvLoader() loader.load() value = loader.get("NON_EXISTING_KEY", "default_value") assert value == "default_value" def test_get_non_existing_key_without_default(self): """测试获取不存在的环境变量(不带默认值)""" loader = EnvLoader() loader.load() value = loader.get("NON_EXISTING_KEY") assert value is None def test_get_int_existing_key(self): """测试获取整数类型的环境变量""" with patch.dict(os.environ, {"INT_KEY": "123"}): loader = EnvLoader() loader.load() value = loader.get_int("INT_KEY") assert value == 123 def test_get_int_non_existing_key_with_default(self): """测试获取不存在的整数环境变量(带默认值)""" loader = EnvLoader() loader.load() value = loader.get_int("NON_EXISTING_INT", 456) assert value == 456 def test_get_int_invalid_value(self): """测试获取无效的整数环境变量""" with patch.dict(os.environ, {"INVALID_INT": "not_a_number"}): loader = EnvLoader() loader.load() value = loader.get_int("INVALID_INT", 789) assert value == 789 def test_get_bool_true_values(self): """测试获取布尔类型的环境变量(真值)""" true_values = ["true", "True", "TRUE", "yes", "Yes", "YES", "1", "on", "On", "ON"] for i, value in enumerate(true_values): with patch.dict(os.environ, {f"BOOL_KEY_{i}": value}): loader = EnvLoader() loader.load() bool_value = loader.get_bool(f"BOOL_KEY_{i}") assert bool_value is True def test_get_bool_false_values(self): """测试获取布尔类型的环境变量(假值)""" false_values = ["false", "False", "FALSE", "no", "No", "NO", "0", "off", "Off", "OFF"] for i, value in enumerate(false_values): with patch.dict(os.environ, {f"BOOL_KEY_{i}": value}): loader = EnvLoader() loader.load() bool_value = loader.get_bool(f"BOOL_KEY_{i}") assert bool_value is False def test_get_bool_invalid_value(self): """测试获取无效的布尔环境变量""" with patch.dict(os.environ, {"INVALID_BOOL": "maybe"}): loader = EnvLoader() loader.load() value = loader.get_bool("INVALID_BOOL", False) assert value is False def test_mask_sensitive_value_short(self): """测试掩码短敏感值""" loader = EnvLoader() assert loader.mask_sensitive_value("") == "" assert loader.mask_sensitive_value("a") == "***" assert loader.mask_sensitive_value("ab") == "***" assert loader.mask_sensitive_value("abc") == "***" assert loader.mask_sensitive_value("abcd") == "***" def test_mask_sensitive_value_long(self): """测试掩码长敏感值""" loader = EnvLoader() assert loader.mask_sensitive_value("password123") == "pa***23" assert loader.mask_sensitive_value("secret_key_abc") == "se***bc" assert loader.mask_sensitive_value("token_xyz_123") == "to***23" def test_validate_required_keys_all_present(self): """测试验证必需的键(全部存在)""" required_keys = ["KEY1", "KEY2", "KEY3"] with patch.dict(os.environ, {"KEY1": "value1", "KEY2": "value2", "KEY3": "value3"}): loader = EnvLoader() loader.load() assert loader.validate_required(required_keys) is True def test_validate_required_keys_missing(self): """测试验证必需的键(有缺失)""" required_keys = ["KEY1", "KEY2", "MISSING_KEY"] with patch.dict(os.environ, {"KEY1": "value1", "KEY2": "value2"}): loader = EnvLoader() loader.load() assert loader.validate_required(required_keys) is False def test_global_env_loader_instance(self): """测试全局环境变量加载器实例""" from neobot.core.utils.env_loader import env_loader assert isinstance(env_loader, EnvLoader) assert env_loader.env_file == Path(".env") @pytest.mark.asyncio async def test_async_compatibility(self): """测试异步兼容性""" loader = EnvLoader() loader.load() value = loader.get("NON_EXISTING_ASYNC_KEY", "default") assert value == "default" if __name__ == "__main__": pytest.main([__file__, "-v"])