mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:01:09 +02:00
Applied formatting to 1487+ files using pnpm format:write - TypeScript/JavaScript files - Svelte components - Astro pages - JSON configs - Markdown docs 13 files still need manual review (Astro JSX comments) |
||
|---|---|---|
| .. | ||
| backend | ||
| mobile | ||
| shared | ||
| web | ||
| README.md | ||
Test Examples
This directory contains comprehensive example test files demonstrating best practices for testing different app types in the Manacore monorepo.
Directory Structure
test-examples/
├── backend/ # NestJS backend examples
│ ├── example.controller.spec.ts
│ └── example.service.spec.ts
├── mobile/ # React Native mobile examples
│ ├── ExampleComponent.test.tsx
│ └── authService.test.ts
├── web/ # SvelteKit web examples
│ ├── Button.test.ts
│ └── page.server.test.ts
├── shared/ # Shared package examples
│ └── format.test.ts
└── README.md
Example Files Overview
Backend Tests (NestJS)
example.controller.spec.ts
Demonstrates:
- Controller unit testing with mocked services
- Request/response handling
- Authentication/authorization testing
- Input validation
- Error handling
- CRUD operations
Key Patterns:
- Use
@nestjs/testingTestingModule - Mock all service dependencies
- Test both success and error paths
- Verify service method calls
example.service.spec.ts
Demonstrates:
- Service business logic testing
- Database operation mocking
- External API mocking
- Result pattern for error handling
- Data validation and sanitization
- Authorization checks
Key Patterns:
- Mock database and external services
- Test error handling thoroughly
- Verify data transformations
- Test edge cases and boundary conditions
Mobile Tests (React Native)
ExampleComponent.test.tsx
Demonstrates:
- Component rendering
- User interactions (press, long press)
- State management
- Props validation
- Accessibility testing
- Performance testing
- Snapshot testing
Key Patterns:
- Use
@testing-library/react-native - Test user behavior, not implementation
- Verify accessibility props
- Test loading and error states
authService.test.ts
Demonstrates:
- Async service testing
- API call mocking with fetch
- Storage operations (SecureStore)
- Error handling (network, storage)
- Token management
- Integration with other services
Key Patterns:
- Mock global fetch
- Mock Expo modules (SecureStore)
- Test timeout scenarios
- Verify storage operations
Web Tests (SvelteKit)
Button.test.ts
Demonstrates:
- Svelte 5 component testing
- Reactive state with runes ($state, $derived)
- User events
- Accessibility
- Variants and sizes
- Custom events
- Debouncing
Key Patterns:
- Use
@testing-library/svelte - Test Svelte 5 reactivity
- Verify accessibility attributes
- Test custom event dispatch
page.server.test.ts
Demonstrates:
- Server load function testing
- Form action testing
- Database mocking (PocketBase)
- Authentication checks
- Input validation and sanitization
- Authorization enforcement
- File upload handling
Key Patterns:
- Mock
localsobject - Mock database client
- Test redirect behavior
- Verify authorization logic
- Sanitize user input
Shared Package Tests
format.test.ts
Demonstrates:
- Pure function testing
- Parameterized tests (it.each)
- Edge case testing
- Boundary testing
- Property-based testing
- Security testing (XSS, SQL injection)
- Unicode and emoji handling
Key Patterns:
- Test with multiple inputs using
it.each - Cover edge cases thoroughly
- Test security vulnerabilities
- Verify type safety
How to Use These Examples
1. Copy and Adapt
Copy the relevant example to your project and adapt it:
# Copy backend controller test
cp docs/test-examples/backend/example.controller.spec.ts \
apps/YOUR_PROJECT/apps/backend/src/your-module/__tests__/your.controller.spec.ts
# Update imports and names
2. Follow the Patterns
Each example demonstrates specific testing patterns:
- AAA Pattern: Arrange, Act, Assert
- Descriptive Names: Clear test descriptions
- Mock Management: Proper setup and cleanup
- Error Testing: Both happy and error paths
- Edge Cases: Boundary conditions and special cases
3. Customize for Your Needs
Adapt the examples to your specific requirements:
// Example: Add project-specific mocks
jest.mock('@your-project/custom-service', () => ({
CustomService: {
doSomething: jest.fn(),
},
}));
4. Reference Best Practices
Each file includes comments explaining:
- Why specific patterns are used
- What to test and what not to test
- Common pitfalls to avoid
- Performance considerations
Testing Principles Demonstrated
1. Test Behavior, Not Implementation
// ✅ Good - Testing behavior
it('should display error message when login fails', async () => {
await userEvent.click(loginButton);
expect(screen.getByText('Invalid credentials')).toBeVisible();
});
// ❌ Bad - Testing implementation
it('should set isLoading to false after login', async () => {
await userEvent.click(loginButton);
expect(component.state.isLoading).toBe(false);
});
2. Isolation
Each test should be independent:
beforeEach(() => {
jest.clearAllMocks(); // Clear mock call history
// Reset any state
});
3. Comprehensive Coverage
Cover all code paths:
describe('createItem', () => {
it('should create successfully'); // Happy path
it('should handle validation errors'); // Error path
it('should handle database errors'); // Error path
it('should handle edge cases'); // Edge cases
});
4. Readable Tests
Make tests self-documenting:
describe('User Authentication', () => {
describe('signIn', () => {
it('should sign in successfully with valid credentials', () => {
// Test implementation
});
it('should reject invalid email format', () => {
// Test implementation
});
});
});
Common Test Scenarios
Authentication Testing
it('should require authentication', async () => {
mockEvent.locals = { user: null };
await expect(load(mockEvent)).rejects.toThrow('Redirect');
});
it('should allow access with valid token', async () => {
mockEvent.locals = { user: { id: '123' } };
const result = await load(mockEvent);
expect(result).toBeDefined();
});
Form Validation
it('should validate required fields', async () => {
const formData = new FormData();
formData.append('title', ''); // Invalid
const result = await actions.create(mockEvent);
expect(result.success).toBe(false);
expect(result.error).toContain('required');
});
Error Handling
it('should handle network errors gracefully', async () => {
(global.fetch as jest.Mock).mockRejectedValue(new Error('Network error'));
const result = await authService.signIn('test@example.com', 'password');
expect(result.success).toBe(false);
expect(result.error).toContain('Network');
});
Async Operations
it('should wait for async operation to complete', async () => {
const promise = service.fetchData();
await waitFor(() => {
expect(service.isLoading).toBe(false);
});
const result = await promise;
expect(result).toBeDefined();
});
Testing Checklist
When writing tests, ensure you cover:
- Happy path (successful execution)
- Error paths (validation errors, API errors)
- Edge cases (empty inputs, null values, boundaries)
- Authentication/authorization
- Input sanitization
- Accessibility (for components)
- Loading states
- Error states
- Network failures (for API calls)
- Storage failures (for persistence)
Additional Resources
- Full Testing Strategy
- Implementation Guide
- Shared Test Configurations
- Jest Documentation
- Vitest Documentation
- Testing Library
- Playwright
Contributing
When adding new examples:
- Follow existing naming conventions
- Add comprehensive comments
- Demonstrate best practices
- Cover edge cases
- Update this README
Questions?
- Check the Testing Strategy for overall approach
- Review Implementation Guide for step-by-step instructions
- Look at existing tests in the project for patterns
- Ask in team chat for project-specific guidance