Skip to content

Commit 2b222d4

Browse files
committed
test: add network mocking for example tests
- Add responses library for HTTP mocking - Mock StackOne API calls in tests instead of skipping - Import and execute examples directly to enable mocking - Skip only when optional dependencies are missing
1 parent e92beff commit 2b222d4

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

examples/test_examples.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import subprocess
1+
import importlib.util
2+
import os
23
import sys
34
from pathlib import Path
5+
from typing import Any
46

57
import pytest
8+
import responses
69

710

811
def get_example_files() -> list[str]:
@@ -21,19 +24,64 @@ def get_example_files() -> list[str]:
2124

2225
EXAMPLES = get_example_files()
2326

27+
# Map of example files to required optional packages
28+
OPTIONAL_DEPENDENCIES = {
29+
"openai_integration.py": ["openai"],
30+
"langchain_integration.py": ["langchain_openai"],
31+
"crewai_integration.py": ["crewai"],
32+
}
2433

25-
def test_example_files_exist():
34+
35+
def test_example_files_exist() -> None:
2636
"""Verify that we found example files to test"""
2737
assert len(EXAMPLES) > 0, "No example files found"
2838
print(f"Found {len(EXAMPLES)} examples")
2939

3040

3141
@pytest.mark.parametrize("example_file", EXAMPLES)
32-
def test_run_example(example_file):
42+
@responses.activate
43+
def test_run_example(example_file: str) -> None:
3344
"""Run each example file directly using python"""
45+
# Skip if optional dependencies are not available
46+
if example_file in OPTIONAL_DEPENDENCIES:
47+
for module in OPTIONAL_DEPENDENCIES[example_file]:
48+
try:
49+
__import__(module)
50+
except ImportError:
51+
pytest.skip(f"Skipping {example_file}: {module} not installed")
52+
53+
# Setup mock responses for examples that need them
54+
if example_file in ["index.py", "file_uploads.py"]:
55+
# Mock employee list endpoint
56+
responses.add(
57+
responses.GET,
58+
"https://api.stackone.com/unified/hris/employees",
59+
json={
60+
"data": [
61+
{
62+
"id": "test-employee-1",
63+
"first_name": "John",
64+
"last_name": "Doe",
65+
"email": "john.doe@example.com"
66+
}
67+
]
68+
},
69+
status=200
70+
)
71+
72+
# Mock document upload endpoint
73+
responses.add(
74+
responses.POST,
75+
"https://api.stackone.com/unified/hris/employees/c28xIQaWQ6MzM5MzczMDA2NzMzMzkwNzIwNA/documents/upload",
76+
json={"success": True, "document_id": "test-doc-123"},
77+
status=200
78+
)
79+
3480
example_path = Path(__file__).parent / example_file
35-
result = subprocess.run([sys.executable, str(example_path)], capture_output=True, text=True)
36-
if result.returncode != 0:
37-
print(f"stdout: {result.stdout}")
38-
print(f"stderr: {result.stderr}")
39-
pytest.fail(f"Example {example_file} failed with return code {result.returncode}")
81+
82+
# Import and run the example module directly
83+
spec = importlib.util.spec_from_file_location("example", example_path)
84+
if spec and spec.loader:
85+
module = importlib.util.module_from_spec(spec)
86+
sys.modules["example"] = module
87+
spec.loader.exec_module(module)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ dev = [
5959
"pytest-asyncio>=0.25.3",
6060
"pytest-cov>=6.0.0",
6161
"pytest-snapshot>=0.9.0",
62+
"responses>=0.25.8",
6263
"ruff>=0.9.6",
6364
"stackone-ai",
6465
"types-requests>=2.31.0.20240311",

uv.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)