
test-implement-constructor-validation
by dawiddutoit
Collection of Claude Code skills, agents, and plugins
SKILL.md
name: test-implement-constructor-validation description: | Auto-generate constructor validation tests from service class signatures. Use when creating tests for new services, validating fail-fast principle, ensuring constructor validation, or testing required parameters. Analyzes service init methods and generates pytest.raises(ValueError) tests for each required parameter. Works with Python service classes following dependency injection pattern. High automation opportunity (100+ test classes use this pattern). allowed-tools:
- Read
- Grep
- Glob
- Write
- Edit
- Bash
Implement Constructor Validation Tests
Purpose
Automatically generate comprehensive constructor validation tests for service classes that follow the fail-fast principle. This skill ensures every required parameter has a corresponding test that validates the service raises ValueError when that parameter is None.
When to Use
Use this skill when:
- Creating tests for new services - Generating constructor validation tests automatically
- Validating fail-fast principle - Ensuring services validate required parameters
- Testing constructor validation - Verifying services raise ValueError for None parameters
- Testing required parameters - Validating each required parameter has proper validation
- Following TDD workflow - Creating tests before or alongside service implementation
- Automating test generation - Reducing manual boilerplate for repetitive test patterns
Trigger phrases:
- "Generate constructor validation tests"
- "Test service constructor"
- "Validate fail-fast principle"
- "Test required parameters"
- "Create constructor tests"
Quick Start
Simplest usage - generate tests for a new service:
# 1. Identify the service class you need tests for
# 2. Locate or create the test file
# 3. Invoke this skill with the service file path and test file path
The skill will:
- Extract constructor signature from service class
- Identify all required parameters
- Generate one test method per required parameter
- Include proper fixtures, type ignores, and error message assertions
Table of Contents
Core Sections
- Purpose - Automated constructor validation test generation
- Instructions - Step-by-step test generation process
- Step 1: Analyze Service Constructor - Extract parameters and validation logic
- Step 2: Identify Required Test Fixtures - Mock fixture patterns
- Step 3: Generate Test Class Structure - Test class template
- Step 4: Handle Type Ignore Comments - Suppress pyright errors
- Step 5: Validate Error Messages - Assert specific error messages
- Step 6: Organize Test Methods - Method ordering and fixture exclusion
- Examples - Working implementations
- Example 1: Simple Service (2 Parameters) - ChunkingService pattern
- Example 2: Complex Service (5 Parameters) - IndexingOrchestrator pattern
Supporting Resources
- templates/test-template.py - Copy-paste ready template
- references/reference.md - Pattern analysis and edge cases
Utility Scripts
- Find Missing Validation Tests - Identify services lacking constructor validation tests
- Generate Constructor Tests - Auto-generate pytest test classes from service signatures
- Validate Test Coverage - Verify all constructor parameters have corresponding tests
Advanced Topics
- Requirements - Python 3.11+, pytest, fail-fast validation pattern
- Automation Strategy - Future script for full automation
- See Also - Related documentation
Instructions
Step 1: Analyze Service Constructor
Read the service class to extract:
- Class name (for test naming)
- Constructor parameters and their types
- Validation error messages (from
if not X: raise ValueError("...")blocks) - Dependencies that need mocking
Example Pattern to Look For:
def __init__(
self,
settings: Settings,
indexing_module: IndexingModule,
extractor_registry: ExtractorRegistry,
):
if not settings:
raise ValueError("Settings is required for IndexingOrchestrator")
if not indexing_module:
raise ValueError("IndexingModule is required for IndexingOrchestrator")
# ... more validations
Step 2: Identify Required Test Fixtures
For each constructor parameter:
- Determine if it needs a mock fixture (services, repositories)
- Identify the spec type for mocking
- Check if the service has async methods (use AsyncMock)
Fixture Naming Pattern: mock_{parameter_name}
Step 3: Generate Test Class Structure
Create a dedicated test class for constructor validation:
class Test{ServiceName}Constructor:
"""Test {ServiceName} constructor and initialization."""
# Fixtures for each dependency
@pytest.fixture
def mock_settings(self):
"""Create mock Settings."""
return MagicMock(spec=Settings)
# ... more fixtures
# Success case test
def test_constructor_initializes_with_valid_dependencies(self, ...):
"""Test that constructor properly initializes with all valid dependencies."""
# Arrange + Act
instance = ServiceName(...)
# Assert
assert instance.settings is mock_settings
# ... assert all dependencies
# Validation tests (one per parameter)
def test_constructor_fails_when_{param}_is_none(self, ...):
"""Test that constructor raises ValueError when {Param} is None."""
with pytest.raises(ValueError) as exc_info:
ServiceName(
param=None, # type: ignore
# ... other valid params
)
assert "{Param} is required for {ServiceName}" in str(exc_info.value)
Step 4: Handle Type Ignore Comments
For each None parameter in validation tests:
- Add
# type: ignorecomment on same line - This suppresses pyright errors for intentionally wrong types
- Required because we're testing failure cases
Pattern:
ServiceName(
settings=None, # type: ignore
other_param=mock_other_param,
)
Step 5: Validate Error Messages
Each validation test must assert the specific error message:
assert "{ParamType} is required for {ServiceName}" in str(exc_info.value)
Error Message Pattern from Constructor:
if not settings:
raise ValueError("Settings is required for IndexingOrchestrator")
Step 6: Organize Test Methods
Method Ordering:
- Success case (all valid parameters)
- Validation failures (one per parameter, in parameter order)
Fixture Exclusion Pattern: Each validation test excludes the fixture for the parameter being tested:
def test_constructor_fails_when_settings_is_none(
self,
# mock_settings EXCLUDED - this is what we're testing
mock_indexing_module,
mock_extractor_registry,
):
Examples
Example 1: Simple Service (2 Parameters)
Service Constructor:
class ChunkingService:
def __init__(self, settings: Settings, tokenizer: Tokenizer):
if not settings:
raise ValueError("Settings is required for ChunkingService")
if not tokenizer:
raise ValueError("Tokenizer is required for ChunkingService")
self.settings = settings
self.tokenizer = tokenizer
Generated Tests:
class TestChunkingServiceConstructor:
"""Test ChunkingService constructor and initialization."""
@pytest.fixture
def mock_settings(self):
"""Create mock Settings."""
return MagicMock(spec=Settings)
@pytest.fixture
def mock_tokenizer(self):
"""Create mock Tokenizer."""
return MagicMock(spec=Tokenizer)
def test_constructor_initializes_with_valid_dependencies(
self, mock_settings, mock_tokenizer
):
"""Test that constructor properly initializes with all valid dependencies."""
service = ChunkingService(
settings=mock_settings,
tokenizer=mock_tokenizer,
)
assert service.settings is mock_settings
assert service.tokenizer is mock_tokenizer
def test_constructor_fails_when_settings_is_none(self, mock_tokenizer):
"""Test that constructor raises ValueError when Settings is None."""
with pytest.raises(ValueError) as exc_info:
ChunkingService(
settings=None, # type: ignore
tokenizer=mock_tokenizer,
)
assert "Settings is required for ChunkingService" in str(exc_info.value)
def test_constructor_fails_when_tokenizer_is_none(self, mock_settings):
"""Test that constructor raises ValueError when Tokenizer is None."""
with pytest.raises(ValueError) as exc_info:
ChunkingService(
settings=mock_settings,
tokenizer=None, # type: ignore
)
assert "Tokenizer is required for ChunkingService" in str(exc_info.value)
Example 2: Complex Service (5 Parameters)
For a complex service with 5 parameters, follow the same pattern as Example 1 above. Create a test class with fixtures for each parameter, a success case test, and one validation failure test for each required parameter. See references/reference.md for detailed pattern analysis and edge cases.
Requirements
- Python 3.11+
- pytest installed:
uv pip install pytest - unittest.mock (standard library)
- Service class must follow fail-fast validation pattern
- Service must have
if not param: raise ValueError(...)blocks
Automation Strategy
This skill is a prime candidate for full automation because:
- Highly Repetitive Pattern - 100+ test classes use identical structure
- Deterministic Generation - Output is fully determined by input (constructor signature)
- Clear Rules - No subjective decisions required
- Type Safety - Can validate against service class signature
- Error Message Consistency - Standard format:
"{Type} is required for {Service}"
Future Enhancement: Create a script that:
- Accepts service file path as input
- Parses AST to extract constructor signature
- Generates complete test class with all fixtures and validation tests
- Runs pyright to validate generated tests
- Writes to appropriate test file location
See Also
- templates/test-template.py - Copy-paste template
- references/reference.md - Pattern analysis and edge cases
- CLAUDE.md - Fail-fast principle documentation
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です