3
3
import sys
4
4
import pytest
5
5
from unittest .mock import MagicMock , patch
6
- from typing import Dict , Any
7
6
8
- # Apply global patches before any app modules are imported
7
+ # We need to patch the Settings class before it's imported
8
+ # First, identify the module path of the Settings class
9
+ SETTINGS_MODULE = "app.core.config"
10
+
11
+ # Mock the Settings class
12
+ class MockSettings :
13
+ """A fake settings class that provides all required attributes."""
14
+
15
+ def __init__ (self , ** kwargs ):
16
+ # Set default values for all required settings
17
+ self .PROJECT_NAME = os .environ .get ("PROJECT_NAME" , "Test Project" )
18
+ self .API_V1_STR = "/api/v1"
19
+
20
+ # Database settings
21
+ self .POSTGRES_SERVER = os .environ .get ("POSTGRES_SERVER" , "mock" )
22
+ self .POSTGRES_USER = os .environ .get ("POSTGRES_USER" , "postgres" )
23
+ self .POSTGRES_PASSWORD = os .environ .get ("POSTGRES_PASSWORD" , "postgres" )
24
+ self .POSTGRES_DB = os .environ .get ("POSTGRES_DB" , "postgres" )
25
+ self .SQLALCHEMY_DATABASE_URI = f"postgresql+asyncpg://{ self .POSTGRES_USER } :{ self .POSTGRES_PASSWORD } @{ self .POSTGRES_SERVER } /{ self .POSTGRES_DB } "
26
+
27
+ # Broker settings
28
+ self .BROKER_USER = os .environ .get ("BROKER_USER" , "guest" )
29
+ self .BROKER_PASSWORD = os .environ .get ("BROKER_PASSWORD" , "guest" )
30
+ self .BROKER_HOST = os .environ .get ("BROKER_HOST" , "localhost" )
31
+ self .BROKER_PORT = os .environ .get ("BROKER_PORT" , "5672" )
32
+ self .BROKER_VHOST = os .environ .get ("BROKER_VHOST" , "/" )
33
+ self .CELERY_BROKER_URL = f"amqp://{ self .BROKER_USER } :{ self .BROKER_PASSWORD } @{ self .BROKER_HOST } :{ self .BROKER_PORT } /{ self .BROKER_VHOST } "
34
+ self .CELERY_RESULT_BACKEND = f"rpc://{ self .BROKER_USER } :{ self .BROKER_PASSWORD } @{ self .BROKER_HOST } :{ self .BROKER_PORT } /{ self .BROKER_VHOST } "
35
+
36
+ # ClickHouse settings
37
+ self .CLICKHOUSE_HOST = os .environ .get ("CLICKHOUSE_HOST" , "mock" )
38
+ self .CLICKHOUSE_USERNAME = os .environ .get ("CLICKHOUSE_USERNAME" , "default" )
39
+ self .CLICKHOUSE_PASSWORD = os .environ .get ("CLICKHOUSE_PASSWORD" , "mock_password" )
40
+ self .CLICKHOUSE_DATABASE = os .environ .get ("CLICKHOUSE_DATABASE" , "default" )
41
+
42
+ # Monitoring settings
43
+ self .JAEGER_URL = os .environ .get ("JAEGER_URL" , "http://localhost:14268/api/traces" )
44
+
45
+ # Admin user settings
46
+ self .SUPER_ADMIN_EMAIL = os .environ .get ("SUPER_ADMIN_EMAIL" , "admin@example.com" )
47
+ self .SUPER_ADMIN_USERNAME = os .environ .get ("SUPER_ADMIN_USERNAME" , "admin" )
48
+ self .SUPER_ADMIN_PASSWORD = os .environ .get ("SUPER_ADMIN_PASSWORD" , "admin" )
49
+
50
+ # Add any additional settings your app might need
51
+ # Set all values passed through kwargs
52
+ for key , value in kwargs .items ():
53
+ setattr (self , key , value )
54
+
55
+ # Apply patches before any imports occur
9
56
def pytest_configure (config ):
10
- """Configure test environment before any test modules are loaded."""
11
- # Mock out third-party modules that try to make connections
57
+ """Configure test environment before any modules are loaded."""
58
+ # Set all required environment variables
59
+ required_env_vars = {
60
+ "PROJECT_NAME" : "Test Project" ,
61
+ "POSTGRES_SERVER" : "mock" ,
62
+ "POSTGRES_USER" : "postgres" ,
63
+ "POSTGRES_PASSWORD" : "postgres" ,
64
+ "POSTGRES_DB" : "postgres" ,
65
+ "BROKER_USER" : "guest" ,
66
+ "BROKER_PASSWORD" : "guest" ,
67
+ "BROKER_HOST" : "localhost" ,
68
+ "BROKER_PORT" : "5672" ,
69
+ "BROKER_VHOST" : "/" ,
70
+ "CLICKHOUSE_HOST" : "mock" ,
71
+ "CLICKHOUSE_USERNAME" : "default" ,
72
+ "CLICKHOUSE_PASSWORD" : "mock_password" ,
73
+ "CLICKHOUSE_DATABASE" : "default" ,
74
+ "JAEGER_URL" : "http://localhost:14268/api/traces" ,
75
+ "SUPER_ADMIN_EMAIL" : "admin@example.com" ,
76
+ "SUPER_ADMIN_USERNAME" : "admin" ,
77
+ "SUPER_ADMIN_PASSWORD" : "admin" ,
78
+ }
79
+
80
+ # Set all environment variables
81
+ for key , value in required_env_vars .items ():
82
+ os .environ [key ] = value
83
+
84
+ # Create mock settings instance
85
+ mock_settings = MockSettings ()
86
+
87
+ # Mock modules that might connect to external services
12
88
modules_to_mock = [
13
89
"clickhouse_connect" ,
14
90
"clickhouse_driver" ,
@@ -23,88 +99,37 @@ def pytest_configure(config):
23
99
24
100
# Mock specific functions
25
101
sys .modules ["clickhouse_connect" ].get_client = MagicMock (return_value = MagicMock ())
26
-
27
- # Mock Settings class before it's imported
28
- @pytest .fixture (scope = "session" , autouse = True )
29
- def mock_settings ():
30
- """Mock the Settings class to avoid validation errors."""
31
- # Create a fake settings object with all required attributes
32
- mock_settings = MagicMock ()
33
-
34
- # Add all required attributes
35
- settings_attrs = [
36
- "PROJECT_NAME" , "API_V1_STR" , "POSTGRES_SERVER" , "POSTGRES_USER" ,
37
- "POSTGRES_PASSWORD" , "POSTGRES_DB" , "SQLALCHEMY_DATABASE_URI" ,
38
- "BROKER_USER" , "BROKER_PASSWORD" , "BROKER_HOST" , "BROKER_PORT" ,
39
- "BROKER_VHOST" , "CELERY_BROKER_URL" , "CELERY_RESULT_BACKEND" ,
40
- "CLICKHOUSE_HOST" , "CLICKHOUSE_USERNAME" , "CLICKHOUSE_PASSWORD" ,
41
- "CLICKHOUSE_DATABASE" , "JAEGER_URL" , "SUPER_ADMIN_EMAIL" ,
42
- "SUPER_ADMIN_USERNAME" , "SUPER_ADMIN_PASSWORD"
43
- ]
44
102
45
- # Set attributes to test values
46
- for attr in settings_attrs :
47
- setattr ( mock_settings , attr , f"test_ { attr . lower () } " )
103
+ # Create a patch for app.core.config.Settings
104
+ patcher = patch ( f" { SETTINGS_MODULE } .Settings" , MockSettings )
105
+ patcher . start ( )
48
106
49
- # Special handling for database URIs
50
- mock_settings .SQLALCHEMY_DATABASE_URI = "postgresql+asyncpg://postgres:postgres@localhost:5432/postgres"
51
-
52
- # Apply the patch
53
- with patch ("app.core.config.Settings" , return_value = mock_settings ):
54
- with patch ("app.core.config.settings" , mock_settings ):
55
- yield mock_settings
56
-
57
- @pytest .fixture (scope = "session" , autouse = True )
58
- def setup_env ():
59
- """Setup environment variables for tests."""
60
- # Ensure critical environment variables are set
61
- os .environ .setdefault ("PROJECT_NAME" , "Test Project" )
62
-
63
- # Database env vars
64
- os .environ .setdefault ("POSTGRES_SERVER" , "mock" )
65
- os .environ .setdefault ("POSTGRES_USER" , "postgres" )
66
- os .environ .setdefault ("POSTGRES_PASSWORD" , "postgres" )
67
- os .environ .setdefault ("POSTGRES_DB" , "postgres" )
68
-
69
- # Broker env vars
70
- os .environ .setdefault ("BROKER_USER" , "guest" )
71
- os .environ .setdefault ("BROKER_PASSWORD" , "guest" )
72
- os .environ .setdefault ("BROKER_HOST" , "localhost" )
73
- os .environ .setdefault ("BROKER_PORT" , "5672" )
74
- os .environ .setdefault ("BROKER_VHOST" , "/" )
75
-
76
- # ClickHouse env vars
77
- os .environ .setdefault ("CLICKHOUSE_HOST" , "mock" )
78
- os .environ .setdefault ("CLICKHOUSE_USERNAME" , "default" )
79
- os .environ .setdefault ("CLICKHOUSE_PASSWORD" , "" )
80
- os .environ .setdefault ("CLICKHOUSE_DATABASE" , "default" )
81
-
82
- # Other required env vars
83
- os .environ .setdefault ("JAEGER_URL" , "http://localhost:14268/api/traces" )
84
- os .environ .setdefault ("SUPER_ADMIN_EMAIL" , "admin@example.com" )
85
- os .environ .setdefault ("SUPER_ADMIN_USERNAME" , "admin" )
86
- os .environ .setdefault ("SUPER_ADMIN_PASSWORD" , "admin" )
87
-
88
- yield
107
+ # Create a patch for app.core.config.settings
108
+ settings_patcher = patch (f"{ SETTINGS_MODULE } .settings" , mock_settings )
109
+ settings_patcher .start ()
89
110
90
- # Mock database and external connections
111
+ # Set up mocking for connections
91
112
@pytest .fixture (autouse = True )
92
113
def mock_external_connections (monkeypatch ):
93
114
"""Mock all external connections."""
94
115
# Mock SQLAlchemy
95
116
monkeypatch .setattr ("sqlalchemy.create_engine" , MagicMock ())
96
117
monkeypatch .setattr ("sqlalchemy.ext.asyncio.create_async_engine" , MagicMock ())
97
118
98
- # Mock asyncpg connections
119
+ # Mock asyncpg connections if module exists
99
120
if "asyncpg" in sys .modules :
100
121
monkeypatch .setattr ("asyncpg.connect" , MagicMock ())
101
122
monkeypatch .setattr ("asyncpg.create_pool" , MagicMock ())
102
123
103
- # Mock Celery
124
+ # Mock Celery if module exists
104
125
if "celery" in sys .modules :
105
126
monkeypatch .setattr ("celery.Celery" , MagicMock ())
127
+
128
+ # Mock clickhouse-connect if module exists
129
+ if "clickhouse_connect" in sys .modules :
130
+ monkeypatch .setattr ("clickhouse_connect.get_client" , MagicMock (return_value = MagicMock ()))
106
131
107
- # Example async fixture if needed for other tests
132
+ # Example async fixture
108
133
@pytest .fixture
109
134
async def async_fixture ():
110
135
return "async_value"
0 commit comments