# testing > Testing guide using Vitest. Use when writing tests (.test.ts, .test.tsx), fixing failing tests, improving test coverage, or debugging test issues. Triggers on test creation, test debugging, mock setup, or test-related questions. - Author: hongdang1a8-gif - Repository: hongdang1a8-gif/storyhah - Version: 20260204120325 - Stars: 1 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/hongdang1a8-gif/storyhah - Web: https://mule.run/skillshub/@@hongdang1a8-gif/storyhah~testing:20260204120325 --- --- name: testing description: Testing guide using Vitest. Use when writing tests (.test.ts, .test.tsx), fixing failing tests, improving test coverage, or debugging test issues. Triggers on test creation, test debugging, mock setup, or test-related questions. --- # Testing Guide ## Quick Reference **Commands:** ```bash # Run specific test file npx vitest run '[file-path]' # Run with coverage npx vitest run --coverage # Watch mode npx vitest watch '[file-path]' ``` ## Test Categories | Category | Location | Config | |----------|----------|--------| | Components | `src/**/*.test.tsx` | `vitest.config.ts` | | Services | `services/**/*.test.ts` | `vitest.config.ts` | | Utils | `utils/**/*.test.ts` | `vitest.config.ts` | ## Core Principles 1. **Prefer `vi.spyOn` over `vi.mock`** - More targeted, easier to maintain 2. **Tests must pass type check** - Run `npm run type-check` after writing tests 3. **After 1-2 failed fix attempts, stop and ask for help** 4. **Test behavior, not implementation details** ## Basic Test Structure ```typescript import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; beforeEach(() => { vi.clearAllMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); describe('ModuleName', () => { describe('functionName', () => { it('should handle normal case', () => { // Arrange → Act → Assert }); }); }); ``` ## Mock Patterns ```typescript // ✅ Spy on direct dependencies vi.spyOn(service, 'method').mockResolvedValue('value'); // ✅ Use vi.stubGlobal for browser APIs vi.stubGlobal('Image', mockImage); vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock'); // ❌ Avoid mocking entire modules globally vi.mock('@/services/chat'); // Too broad ``` ## React Component Testing ```typescript import { render, screen, fireEvent } from '@testing-library/react'; describe('Button', () => { it('should call onClick when clicked', () => { const handleClick = vi.fn(); render(); fireEvent.click(screen.getByText('Click me')); expect(handleClick).toHaveBeenCalledTimes(1); }); }); ``` ## Common Issues 1. **Module pollution**: Use `vi.resetModules()` when tests fail mysteriously 2. **Mock not working**: Check setup position and use `vi.clearAllMocks()` in beforeEach 3. **Test data pollution**: Clean state in beforeEach/afterEach 4. **Async issues**: Wrap state changes in `act()` for React hooks ## Test Coverage Goals | Type | Target | |------|--------| | Statements | 80% | | Branches | 75% | | Functions | 80% | | Lines | 80% |