```json { "coaching_level": "standard", "socratic_max_questions": 2, "verbosity": "normal", "timebox_minutes": null, "format_enforcement": "strict" } ``` # Unit Testing & Mocks β€” Universal Development Guide **Author**: Matthew Raymer **Date**: 2025-08-21T09:40Z **Status**: 🎯 **ACTIVE** - Comprehensive testing standards ## Overview This guide establishes **unified unit testing and mocking standards** for Vue and React projects, ensuring consistent, maintainable test patterns using Vitest, JSDOM, and component testing utilities. All tests follow F.I.R.S.T. principles with comprehensive mock implementations. ## Scope and Goals **Scope**: Applies to all unit tests, mock implementations, and testing infrastructure in any project workspace. **Goal**: One consistent testing approach with comprehensive mock coverage, 100% test coverage for simple components, and maintainable test patterns. ## Non‑Negotiables (DO THIS) - **MUST** use Vitest + JSDOM for unit testing; **DO NOT** use Jest or other frameworks - **MUST** implement comprehensive mock levels (Simple, Standard, Complex) for all components - **MUST** achieve 100% line coverage for simple components (<100 lines) - **MUST** follow F.I.R.S.T. principles: Fast, Independent, Repeatable, Self-validating, Timely - **MUST** use centralized test utilities from `src/test/utils/` ## Testing Infrastructure ### **Core Technologies** - **Vitest**: Fast unit testing framework with Vue/React support - **JSDOM**: Browser-like environment for Node.js testing - **@vue/test-utils**: Vue component testing utilities - **TypeScript**: Full type safety for tests and mocks ### **Configuration Files** - `vitest.config.ts` - Vitest configuration with JSDOM environment - `src/test/setup.ts` - Global test configuration and mocks - `src/test/utils/` - Centralized testing utilities ### **Global Mocks** ```typescript // Required browser API mocks ResizeObserver, IntersectionObserver, localStorage, sessionStorage, matchMedia, console methods (reduced noise) ``` ## Mock Implementation Standards ### **Mock Architecture Levels** #### **1. Simple Mock (Basic Testing)** ```typescript // Minimal interface compliance class ComponentSimpleMock { // Essential props and methods only // Basic computed properties // No complex behavior } ``` #### **2. Standard Mock (Integration Testing)** ```typescript // Full interface compliance class ComponentStandardMock { // All props, methods, computed properties // Realistic behavior simulation // Helper methods for test scenarios } ``` #### **3. Complex Mock (Advanced Testing)** ```typescript // Enhanced testing capabilities class ComponentComplexMock extends ComponentStandardMock { // Mock event listeners // Performance testing hooks // Error scenario simulation // Accessibility testing support } ``` ### **Mock Component Structure** Each mock component provides: - Same interface as original component - Simplified behavior for testing - Helper methods for test scenarios - Computed properties for state validation ### **Enhanced Mock Architecture Validation** βœ… **NEW** The three-tier mock architecture (Simple/Standard/Complex) has been successfully validated through real-world implementation: #### **Tier 1: Simple Mock** ```typescript class ComponentSimpleMock { // Basic interface compliance // Minimal implementation for simple tests // Fast execution for high-volume testing } ``` #### **Tier 2: Standard Mock** ```typescript class ComponentStandardMock { // Full interface implementation // Realistic behavior simulation // Helper methods for common scenarios } ``` #### **Tier 3: Complex Mock** ```typescript class ComponentComplexMock { // Enhanced testing capabilities // Validation and error simulation // Advanced state management // Performance testing support } ``` #### **Factory Function Pattern** ```typescript // Specialized factory functions for common use cases export const createComponentMock = () => new ComponentStandardMock({ type: 'default' }) export const createSpecializedMock = () => new ComponentComplexMock({ options: { filter: 'active', sort: 'name' } }) ``` ### **Mock Usage Examples** ```typescript export default class ComponentMock { // Props simulation props: ComponentProps // Computed properties get computedProp(): boolean { return this.props.condition } // Mock methods mockMethod(): void { // Simulate behavior } // Helper methods getCssClasses(): string[] { return ['base-class', 'conditional-class'] } } ``` ## Test Patterns ### **Component Testing Template** ```typescript import { mount } from '@vue/test-utils' import { createComponentWrapper } from '@/test/utils/componentTestUtils' describe('ComponentName', () => { let wrapper: VueWrapper const mountComponent = (props = {}) => { return mount(ComponentName, { props: { ...defaultProps, ...props } }) } beforeEach(() => { wrapper = mountComponent() }) afterEach(() => { wrapper?.unmount() }) describe('Component Rendering', () => { it('should render correctly', () => { expect(wrapper.exists()).toBe(true) }) }) }) ``` ### **Mock Integration Testing** ```typescript import ComponentMock from '@/test/__mocks__/Component.mock' it('should work with mock component', () => { const mock = new ComponentMock() expect(mock.shouldShow).toBe(true) }) ``` ### **Event Testing** ```typescript it('should emit event when triggered', async () => { await wrapper.find('button').trigger('click') expect(wrapper.emitted('event-name')).toBeTruthy() }) ``` ### **Prop Validation** ```typescript it('should accept all required props', () => { wrapper = mountComponent() expect(wrapper.vm.propName).toBeDefined() }) ``` ## Test Categories ### **Required Coverage Areas** 1. **Component Rendering** - Existence, structure, conditional rendering 2. **Component Styling** - CSS classes, responsive design, framework integration 3. **Component Props** - Required/optional prop handling, type validation 4. **User Interactions** - Click events, form inputs, keyboard navigation 5. **Component Methods** - Method existence, functionality, return values 6. **Edge Cases** - Empty/null props, rapid interactions, state changes 7. **Error Handling** - Invalid props, malformed data, graceful degradation 8. **Accessibility** - Semantic HTML, ARIA attributes, keyboard navigation 9. **Performance** - Render time, memory leaks, rapid re-renders 10. **Integration** - Parent-child interaction, dependency injection ### **Error Handling Testing** ```typescript const invalidPropCombinations = [ null, undefined, 'invalid', 0, -1, {}, [], () => {}, NaN, Infinity ] invalidPropCombinations.forEach(invalidProp => { it(`should handle invalid prop: ${invalidProp}`, () => { wrapper = mountComponent({ prop: invalidProp }) expect(wrapper.exists()).toBe(true) // Verify graceful handling }) }) ``` ## Centralized Test Utilities ### **Component Testing Utilities** ```typescript import { createComponentWrapper, createTestDataFactory, testLifecycleEvents, testComputedProperties, testWatchers, testPerformance, testAccessibility, testErrorHandling } from '@/test/utils/componentTestUtils' // Component wrapper factory const wrapperFactory = createComponentWrapper( Component, defaultProps, globalOptions ) // Test data factory const createTestProps = createTestDataFactory({ prop1: 'default', prop2: true }) ``` ### **Test Data Factories** ```typescript import { createMockContact, createMockProject, createMockUser } from '@/test/factories/contactFactory' const testContact = createMockContact({ id: 'test-1', name: 'Test User' }) ``` ## Coverage Standards ### **Coverage Standards by Component Complexity** | Component Complexity | Line Coverage | Branch Coverage | Function Coverage | |---------------------|---------------|-----------------|-------------------| | **Simple (<100 lines)** | 100% | 100% | 100% | | **Medium (100-300 lines)** | 95% | 90% | 100% | | **Complex (300+ lines)** | 90% | 85% | 100% | ### **Current Coverage Status** - **Simple Components**: Ready for implementation - **Medium Components**: Ready for expansion - **Complex Components**: Ready for expansion - **Overall Coverage**: Varies by project implementation ### **Test Infrastructure Requirements** - **Test Framework**: Vitest + JSDOM recommended - **Component Testing**: Vue Test Utils integration - **Mock Architecture**: Three-tier system (Simple/Standard/Complex) - **Test Categories**: 10 comprehensive categories - **Coverage Goals**: 100% for simple components, 90%+ for complex ## Testing Philosophy ### **Defensive Programming Validation** - **Real-world edge case protection** against invalid API responses - **System stability assurance** preventing cascading failures - **Production readiness** ensuring graceful error handling ### **Comprehensive Error Scenarios** - **Invalid input testing** with 10+ different invalid prop combinations - **Malformed data testing** with various corrupted data structures - **Extreme value testing** with boundary conditions and edge cases - **Concurrent error testing** with rapid state changes ### **Benefits Beyond Coverage** 1. **Defensive Programming Validation** - Components handle unexpected data gracefully 2. **Real-World Resilience** - Tested against actual failure scenarios 3. **Developer Confidence** - Safe to refactor and extend components 4. **Production Stability** - Reduced support tickets and user complaints ## Advanced Testing Patterns ### **Performance Testing** βœ… **NEW** - Render time benchmarks - Memory leak detection - Rapid re-render efficiency - Component cleanup validation #### **Advanced Performance Testing Patterns** ```typescript // Memory leak detection it('should not cause memory leaks during prop changes', async () => { const initialMemory = (performance as any).memory?.usedJSHeapSize || 0 for (let i = 0; i < 100; i++) { await wrapper.setProps({ queryParams: { iteration: i.toString() } }) } const finalMemory = (performance as any).memory?.usedJSHeapSize || 0 const memoryIncrease = finalMemory - initialMemory // Memory increase should be reasonable (less than 10MB) expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024) }) // Rapid re-render efficiency it('should handle rapid re-renders efficiently', async () => { const start = performance.now() for (let i = 0; i < 50; i++) { await wrapper.setProps({ entityType: i % 2 === 0 ? 'type1' : 'type2', queryParams: { index: i.toString() } }) } const end = performance.now() expect(end - start).toBeLessThan(500) // 500ms threshold for 50 updates }) ``` ### **Snapshot Testing** βœ… **NEW** - DOM structure validation - CSS class regression detection - Accessibility attribute consistency - Visual structure verification #### **Snapshot Testing Implementation** ```typescript describe('Snapshot Testing', () => { it('should maintain consistent DOM structure', () => { expect(wrapper.html()).toMatchSnapshot() }) it('should maintain consistent structure with different props', () => { wrapper = mountComponent({ type: 'alternative' }) expect(wrapper.html()).toMatchSnapshot() }) it('should maintain consistent structure with query params', () => { wrapper = mountComponent({ queryParams: { filter: 'active', sort: 'name' } }) expect(wrapper.html()).toMatchSnapshot() }) }) ``` ### **Mock Integration Testing** βœ… **NEW** - Mock component validation - Factory function testing - Mock behavior verification - Integration with testing utilities #### **Mock Integration Testing Patterns** ```typescript describe('Mock Integration Testing', () => { it('should work with simple mock', () => { const mock = new ComponentSimpleMock() expect(mock.navigationRoute).toEqual({ name: 'default', query: {} }) }) it('should work with standard mock', () => { const mock = new ComponentStandardMock({ type: 'special', name: 'test' }) expect(mock.getType()).toBe('special') expect(mock.getName()).toBe('test') }) it('should work with complex mock', () => { const mock = new ComponentComplexMock({ type: 'advanced', options: { filter: 'active' } }) expect(mock.isValidState()).toBe(true) expect(mock.getValidationErrors()).toEqual([]) }) it('should work with factory functions', () => { const defaultMock = createComponentMock() const specializedMock = createSpecializedMock() expect(defaultMock.getType()).toBe('default') expect(specializedMock.getOptions()).toHaveProperty('filter') }) }) ``` ## Project Implementation Tracking ### **Setting Up Project-Specific Tracking** Each project should maintain its own tracking file to monitor testing progress and coverage metrics. This keeps the universal MDC clean while providing a template for project implementation. #### **Recommended Project Tracking Structure** ```tree src/test/ β”œβ”€β”€ README.md # Testing documentation β”œβ”€β”€ PROJECT_COVERAGE_TRACKING.md # Project-specific progress tracking β”œβ”€β”€ __mocks__/ # Mock implementations β”œβ”€β”€ utils/ # Test utilities └── [test files] ``` #### **Project Tracking File Template** Create a `PROJECT_COVERAGE_TRACKING.md` file with: - **Current Coverage Status**: Component-by-component breakdown - **Implementation Progress**: Phase completion status - **Test Infrastructure Status**: Framework setup and metrics - **Next Steps**: Immediate priorities and long-term goals - **Lessons Learned**: Project-specific insights and best practices #### **Example Project Tracking Sections** ```markdown # [Project Name] Testing Coverage Tracking ## Current Coverage Status - Simple Components: X/Y at 100% coverage - Medium Components: X/Y ready for expansion - Complex Components: X/Y planned ## Implementation Progress - Phase 1: Simple Components βœ… COMPLETE - Phase 2: Medium Components πŸ”„ IN PROGRESS - Phase 3: Complex Components πŸ”„ PLANNED ## Test Infrastructure Status - Total Tests: X tests passing - Test Files: X files - Mock Files: X implementations - Overall Coverage: X% (focused on simple components) ``` ### **Integration with Universal MDC** - **MDC provides**: Testing patterns, mock architecture, best practices - **Project tracking provides**: Implementation status, coverage metrics, progress - **Separation ensures**: MDC remains reusable, project data stays local - **Template approach**: Other projects can copy and adapt the structure ### **Benefits of This Approach** 1. **Universal Reusability**: MDC works for any project 2. **Project Visibility**: Clear tracking of implementation progress 3. **Template Reuse**: Easy to set up tracking in new projects 4. **Clean Separation**: No project data polluting universal guidance 5. **Scalability**: Multiple projects can use the same MDC ## Best Practices ### **Test Organization** 1. **Group related tests** using `describe` blocks 2. **Use descriptive test names** that explain the scenario 3. **Keep tests focused** on one specific behavior 4. **Use helper functions** for common setup ### **Mock Design** 1. **Maintain interface compatibility** with original components 2. **Provide helper methods** for common test scenarios 3. **Include computed properties** for state validation 4. **Document mock behavior** clearly ### **Coverage Goals** 1. **100% line coverage** for simple components 2. **100% branch coverage** for conditional logic 3. **100% function coverage** for all methods 4. **Edge case coverage** for error scenarios ### **Lessons Learned from Implementation** βœ… **NEW** #### **1. Performance Testing Best Practices** - **Memory leak detection**: Use `performance.memory.usedJSHeapSize` for memory profiling - **Render time benchmarking**: Set realistic thresholds (100ms for single render, 500ms for 50 updates) - **Rapid re-render testing**: Test with 50+ prop changes to ensure stability #### **2. Snapshot Testing Implementation** - **DOM structure validation**: Use `toMatchSnapshot()` for consistent structure verification - **Prop variation testing**: Test snapshots with different prop combinations - **Regression prevention**: Snapshots catch unexpected DOM changes #### **3. Mock Integration Validation** - **Mock self-testing**: Test that mocks work correctly with testing utilities - **Factory function testing**: Validate specialized factory functions - **Mock behavior verification**: Ensure mocks simulate real component behavior #### **4. Edge Case Coverage** - **Null/undefined handling**: Test with `null as any` and `undefined` props - **Extreme values**: Test with very long strings and large numbers - **Rapid changes**: Test with rapid prop changes to ensure stability #### **5. Accessibility Testing** - **Semantic structure**: Verify proper HTML elements and hierarchy - **Component attributes**: Check component-specific attributes - **Text content**: Validate text content and trimming ## Future Improvements ### **Implemented Enhancements** 1. βœ… **Error handling** - Component error states and exception handling 2. βœ… **Performance testing** - Render time benchmarks and memory leak detection 3. βœ… **Integration testing** - Parent-child component interaction and dependency injection 4. βœ… **Snapshot testing** - DOM structure validation and CSS class regression detection 5. βœ… **Accessibility compliance** - ARIA attributes and semantic structure validation ### **Future Enhancements** 1. **Visual regression testing** - Automated UI consistency checks 2. **Cross-browser compatibility** testing 3. **Service layer integration** testing 4. **End-to-end component** testing 5. **Advanced performance** profiling ### **Coverage Expansion** 1. **Medium complexity components** (100-300 lines) 2. **Complex components** (300+ lines) 3. **Service layer testing** 4. **Utility function testing** 5. **API integration testing** ## Troubleshooting ### **Common Issues** 1. **Import errors**: Check path aliases in `vitest.config.ts` 2. **Mock not found**: Verify mock file exists and exports correctly 3. **Test failures**: Check for timing issues with async operations 4. **Coverage gaps**: Add tests for uncovered code paths ### **Debug Tips** 1. **Use `console.log`** in tests for debugging 2. **Check test output** for detailed error messages 3. **Verify component props** are being passed correctly 4. **Test one assertion at a time** to isolate issues --- **Status**: Active testing standards **Priority**: High **Estimated Effort**: Ongoing reference **Dependencies**: Vitest, JSDOM, Vue Test Utils **Stakeholders**: Development team, QA team ## Competence Hooks - *Why this works*: Three-tier mock architecture provides flexibility, comprehensive test categories ensure thorough coverage, performance testing catches real-world issues early - *Common pitfalls*: Not testing mocks themselves, missing edge case coverage, ignoring performance implications - *Next skill unlock*: Implement medium complexity component testing with established patterns - *Teach-back*: Explain how the three-tier mock architecture supports different testing needs ## Collaboration Hooks - **Reviewers**: Testing team, component developers, architecture team - **Sign-off checklist**: All simple components at 100% coverage, mock utilities documented, test patterns established, coverage expansion plan approved ## Assumptions & Limits - Assumes Vue/React component architecture - Requires Vitest + JSDOM testing environment - Mock complexity scales with component complexity - Performance testing requires browser-like environment ## References - [Vitest Documentation](https://vitest.dev/) - [Vue Test Utils](https://test-utils.vuejs.org/) - [JSDOM](https://github.com/jsdom/jsdom) - [Testing Best Practices](https://testing-library.com/docs/guiding-principles) - **Sign-off checklist**: All simple components at 100% coverage, mock utilities documented, test patterns established, coverage expansion plan approved