test: mock OncoTree API calls to make tests deterministic
Browse filesFixed test_map_project_id_oncotree_hierarchy to mock OncoTree API
instead of making real network calls, ensuring CI is deterministic
and can run offline.
Issue:
- test_map_project_id_oncotree_hierarchy made real HTTP calls to
oncotree.mskcc.org API
- Made test suite flaky and offline-dependent
- Could fail due to network issues or API downtime
- Not suitable for CI environments
Solution:
- Added @patch decorator to mock _get_oncotree_ancestors()
- Mock returns controlled hierarchy: IDC → BRCA → TISSUE
- Tests the ancestor/descendant matching logic in isolation
- No network calls, fully deterministic
Testing:
- Test now passes without network access
- All 54 TCGA tests pass (54/54)
- Test runs faster (no network latency)
- CI-friendly and deterministic
Co-Authored-By: Claude (claude-sonnet-4.5) <noreply@anthropic.com>
- tests/test_tcga.py +20 -6
|
@@ -175,12 +175,26 @@ class TestMetadataMapping:
|
|
| 175 |
assert _map_project_id_to_cancer_subtype("TCGA-COAD") == "COAD"
|
| 176 |
assert _map_project_id_to_cancer_subtype("TCGA-BLCA") == "BLCA"
|
| 177 |
|
| 178 |
-
|
|
|
|
| 179 |
"""Test TCGA project IDs that map via OncoTree hierarchy.
|
| 180 |
|
| 181 |
-
|
|
|
|
| 182 |
BRCA -> IDC (IDC is a child of BRCA in OncoTree)
|
| 183 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
# TCGA-BRCA should map to IDC (child in OncoTree with Paladin models)
|
| 185 |
result = _map_project_id_to_cancer_subtype("TCGA-BRCA")
|
| 186 |
# Should find IDC as it's a descendant of BRCA
|
|
@@ -225,7 +239,9 @@ class TestConvertGDCMetadata:
|
|
| 225 |
{
|
| 226 |
"demographic": {"gender": "female"},
|
| 227 |
"primary_site": "Breast",
|
| 228 |
-
"project": {
|
|
|
|
|
|
|
| 229 |
"samples": [{"sample_type": "Primary Tumor"}],
|
| 230 |
}
|
| 231 |
],
|
|
@@ -319,9 +335,7 @@ class TestGDCAPIIntegration:
|
|
| 319 |
"""Test successful barcode to UUID conversion."""
|
| 320 |
mock_response = MagicMock()
|
| 321 |
mock_response.json.return_value = {
|
| 322 |
-
"data": {
|
| 323 |
-
"hits": [{"file_id": "test-uuid-12345", "file_name": "slide.svs"}]
|
| 324 |
-
}
|
| 325 |
}
|
| 326 |
mock_request.return_value = mock_response
|
| 327 |
|
|
|
|
| 175 |
assert _map_project_id_to_cancer_subtype("TCGA-COAD") == "COAD"
|
| 176 |
assert _map_project_id_to_cancer_subtype("TCGA-BLCA") == "BLCA"
|
| 177 |
|
| 178 |
+
@patch("mosaic.tcga._get_oncotree_ancestors")
|
| 179 |
+
def test_map_project_id_oncotree_hierarchy(self, mock_get_ancestors):
|
| 180 |
"""Test TCGA project IDs that map via OncoTree hierarchy.
|
| 181 |
|
| 182 |
+
Mocks OncoTree API to test ancestor/descendant matching logic
|
| 183 |
+
without making real network calls.
|
| 184 |
BRCA -> IDC (IDC is a child of BRCA in OncoTree)
|
| 185 |
"""
|
| 186 |
+
|
| 187 |
+
# Mock the OncoTree hierarchy:
|
| 188 |
+
# IDC is a descendant of BRCA (IDC has BRCA as ancestor)
|
| 189 |
+
def mock_ancestors(code):
|
| 190 |
+
if code == "IDC":
|
| 191 |
+
return ["BRCA", "TISSUE"] # IDC's ancestors
|
| 192 |
+
elif code == "BRCA":
|
| 193 |
+
return ["TISSUE"] # BRCA's ancestors
|
| 194 |
+
return []
|
| 195 |
+
|
| 196 |
+
mock_get_ancestors.side_effect = mock_ancestors
|
| 197 |
+
|
| 198 |
# TCGA-BRCA should map to IDC (child in OncoTree with Paladin models)
|
| 199 |
result = _map_project_id_to_cancer_subtype("TCGA-BRCA")
|
| 200 |
# Should find IDC as it's a descendant of BRCA
|
|
|
|
| 239 |
{
|
| 240 |
"demographic": {"gender": "female"},
|
| 241 |
"primary_site": "Breast",
|
| 242 |
+
"project": {
|
| 243 |
+
"project_id": "TCGA-LUAD"
|
| 244 |
+
}, # Use LUAD for predictable result
|
| 245 |
"samples": [{"sample_type": "Primary Tumor"}],
|
| 246 |
}
|
| 247 |
],
|
|
|
|
| 335 |
"""Test successful barcode to UUID conversion."""
|
| 336 |
mock_response = MagicMock()
|
| 337 |
mock_response.json.return_value = {
|
| 338 |
+
"data": {"hits": [{"file_id": "test-uuid-12345", "file_name": "slide.svs"}]}
|
|
|
|
|
|
|
| 339 |
}
|
| 340 |
mock_request.return_value = mock_response
|
| 341 |
|