Writing effective dry_run.py mocks for workflow testing without external dependencies
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
npx agent-skills-cli listSkill Instructions
name: mock-authoring description: Writing effective dry_run.py mocks for workflow testing without external dependencies
Mock Authoring Skill
Use this skill to write dry_run.py files that enable workflows to run without external dependencies.
Purpose of dry_run.py
The dry run file provides mock implementations of external operations so workflows can be tested without:
- Network calls (APIs, databases, web scraping)
- File system writes outside the workflow directory
- Environment variables or credentials
- Long-running operations
Mock Patterns
1. API Response Mocking
#!/usr/bin/env python3
"""Dry run with mock data."""
from raw_runtime import DryRunContext
def mock_fetch_stock_price(ctx: DryRunContext, symbol: str) -> dict:
"""Mock Yahoo Finance API response."""
ctx.log(f"[MOCK] Fetching stock price for {symbol}")
# Return realistic mock data
return {
"symbol": symbol,
"price": 150.23,
"change": 2.45,
"change_percent": 1.65,
"volume": 1234567,
"timestamp": "2024-01-15T16:00:00Z"
}
def mock_fetch_news(ctx: DryRunContext, query: str) -> list[dict]:
"""Mock news API response."""
ctx.log(f"[MOCK] Fetching news for query: {query}")
return [
{
"title": "Sample News Article 1",
"url": "https://example.com/article1",
"published": "2024-01-15T10:00:00Z",
"summary": "This is a mock news article summary."
},
{
"title": "Sample News Article 2",
"url": "https://example.com/article2",
"published": "2024-01-15T09:00:00Z",
"summary": "Another mock article summary."
}
]
2. Database Operation Mocking
def mock_query_database(ctx: DryRunContext, sql: str) -> list[dict]:
"""Mock database query."""
ctx.log(f"[MOCK] Executing SQL: {sql[:50]}...")
# Return mock rows
return [
{"id": 1, "name": "Alice", "email": "alice@example.com"},
{"id": 2, "name": "Bob", "email": "bob@example.com"},
]
def mock_insert_record(ctx: DryRunContext, table: str, data: dict) -> int:
"""Mock database insert."""
ctx.log(f"[MOCK] Inserting into {table}: {data}")
return 123 # Mock generated ID
3. File Operation Mocking
def mock_write_file(ctx: DryRunContext, path: str, content: str) -> bool:
"""Mock file write operation."""
ctx.log(f"[MOCK] Would write {len(content)} bytes to {path}")
# Don't actually write - just log
return True
def mock_upload_to_s3(ctx: DryRunContext, bucket: str, key: str, data: bytes) -> str:
"""Mock S3 upload."""
ctx.log(f"[MOCK] Would upload {len(data)} bytes to s3://{bucket}/{key}")
return f"https://s3.amazonaws.com/{bucket}/{key}" # Mock URL
4. Long-Running Operation Mocking
def mock_train_model(ctx: DryRunContext, dataset_path: str) -> dict:
"""Mock ML model training (skip actual training)."""
ctx.log(f"[MOCK] Would train model on {dataset_path}")
ctx.log("[MOCK] Training skipped in dry run")
# Return mock metrics
return {
"accuracy": 0.92,
"precision": 0.89,
"recall": 0.91,
"model_path": "/tmp/mock_model.pkl"
}
DryRunContext Usage
from raw_runtime import DryRunContext
def mock_operation(ctx: DryRunContext) -> str:
# Log what would happen
ctx.log("Starting mock operation")
ctx.log("Step 1: Connect to API")
ctx.log("Step 2: Fetch data")
ctx.log("Step 3: Process results")
# Return mock result
return "mock_result"
Realistic Mock Data
Mock data should be realistic enough to test workflow logic:
# Good: Realistic structure and values
def mock_api_response(ctx: DryRunContext) -> dict:
return {
"status": "success",
"data": [
{"id": "abc123", "value": 42.5, "timestamp": "2024-01-15T10:00:00Z"},
{"id": "def456", "value": 38.2, "timestamp": "2024-01-15T11:00:00Z"},
],
"pagination": {"page": 1, "total_pages": 5}
}
# Bad: Oversimplified mock
def mock_api_response(ctx: DryRunContext) -> dict:
return {"result": "ok"} # Too simple - doesn't match real API
Error Case Mocking
Include mock error scenarios for testing error handling:
def mock_api_with_error(ctx: DryRunContext, should_fail: bool = False) -> dict:
"""Mock API that can simulate failures."""
if should_fail:
ctx.log("[MOCK] Simulating API error")
raise ConnectionError("Mock API connection failed")
ctx.log("[MOCK] API call succeeded")
return {"status": "success", "data": []}
Integration with Workflow
In your workflow run.py:
class MyWorkflow(BaseWorkflow[MyParams]):
def __init__(self, params: MyParams, workflow_dir: Path):
super().__init__(params, workflow_dir)
# Check if running in dry mode
if self.is_dry_run():
# Import mocks
from dry_run import mock_fetch_stock_price, mock_write_file
self.fetch_stock_price = mock_fetch_stock_price
self.write_file = mock_write_file
else:
# Use real implementations
from tools.yahoo_finance import fetch_stock_price
from tools.file_writer import write_file
self.fetch_stock_price = fetch_stock_price
self.write_file = write_file
Testing Your Mocks
# Run workflow in dry mode
raw run <workflow-id> --dry
# Should complete without:
# - Network errors
# - Missing credentials
# - File system permission errors
# - Long wait times
Common Mistakes
-
Mocks that call real APIs
# Bad: Still makes real network call def mock_fetch(ctx: DryRunContext): import requests return requests.get("https://api.example.com") # Don't do this! # Good: Pure mock def mock_fetch(ctx: DryRunContext): ctx.log("[MOCK] Fetching data") return {"data": "mock_value"} -
Accessing environment variables
# Bad: Requires env vars in dry run def mock_auth(ctx: DryRunContext): api_key = os.environ["API_KEY"] # Will fail without env var # Good: No env var dependency def mock_auth(ctx: DryRunContext): ctx.log("[MOCK] Using mock credentials") return "mock_token" -
File system writes outside workflow directory
# Bad: Writes to filesystem def mock_save(ctx: DryRunContext, data: str): with open("/tmp/output.txt", "w") as f: f.write(data) # Good: Just logs def mock_save(ctx: DryRunContext, data: str): ctx.log(f"[MOCK] Would save {len(data)} bytes to /tmp/output.txt")
Checklist for Good Mocks
- No network calls (HTTP, database, etc.)
- No environment variable dependencies
- No file system writes outside workflow directory
- Realistic data structures matching real API responses
- Appropriate use of
ctx.log()for observability - Fast execution (no sleep or long operations)
- Include error cases where workflow handles errors
- Return types match real implementation
More by mpuig
View allDiscover AWS infrastructure and save to JSON. Use when user asks to "discover AWS", "explore AWS account", "scan AWS infrastructure", or "create infrastructure JSON".
Generate AWS architecture diagrams from infrastructure JSON. Use when user asks to "generate diagram", "create AWS diagram", "visualize infrastructure", or "draw architecture".
Guide for creating structured plans with numbered steps and quality gates
Create Agent Skills that comply with the agentskills.io specification. Use when the user asks to create a new skill, add agent capabilities, or build reusable instructions.
