Migrating rules to new format but they should be re-written entirely, I don't think they help much and are not auto-included (except architecture)
90 lines
2.3 KiB
Plaintext
90 lines
2.3 KiB
Plaintext
---
|
|
description:
|
|
globs:
|
|
alwaysApply: false
|
|
---
|
|
# Testing Guidelines
|
|
|
|
## Test Structure (AAA Pattern)
|
|
```typescript
|
|
describe('UserService', () => {
|
|
describe('when getting user by ID', () => {
|
|
it('should return user data for valid ID', async () => {
|
|
// Arrange
|
|
const userId = '123';
|
|
const expectedUser = { id: '123', name: 'John' };
|
|
mockUserRepository.findById.mockResolvedValue(expectedUser);
|
|
|
|
// Act
|
|
const result = await userService.getUserById(userId);
|
|
|
|
// Assert
|
|
expect(result).toEqual(expectedUser);
|
|
});
|
|
});
|
|
});
|
|
```
|
|
|
|
## React Component Testing
|
|
```typescript
|
|
// ✅ Test user behavior, not implementation
|
|
describe('LoginForm', () => {
|
|
it('should display error message for invalid credentials', async () => {
|
|
const mockOnSubmit = jest.fn().mockRejectedValue(new Error('Invalid credentials'));
|
|
render(<LoginForm onSubmit={mockOnSubmit} />);
|
|
|
|
await user.type(screen.getByLabelText(/email/i), 'invalid@example.com');
|
|
await user.type(screen.getByLabelText(/password/i), 'wrongpassword');
|
|
await user.click(screen.getByRole('button', { name: /sign in/i }));
|
|
|
|
expect(await screen.findByText(/invalid credentials/i)).toBeInTheDocument();
|
|
});
|
|
});
|
|
```
|
|
|
|
## Mocking Patterns
|
|
```typescript
|
|
// ✅ Service mocking
|
|
const mockEmailService = {
|
|
sendEmail: jest.fn().mockResolvedValue({ success: true }),
|
|
validateEmail: jest.fn().mockReturnValue(true),
|
|
};
|
|
|
|
// ✅ Test data factories
|
|
const createTestUser = (overrides = {}) => ({
|
|
id: uuid(),
|
|
email: 'test@example.com',
|
|
name: 'Test User',
|
|
...overrides,
|
|
});
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
```
|
|
|
|
## Testing Principles
|
|
- **Test behavior, not implementation** - Focus on what users see/do
|
|
- **Use descriptive test names** - "should [behavior] when [condition]"
|
|
- **Query by user-visible elements** - text, roles, labels over test IDs
|
|
- **Keep tests isolated** - Independent and repeatable
|
|
- **70% unit, 20% integration, 10% E2E** - Test pyramid
|
|
|
|
## Common Patterns
|
|
```typescript
|
|
// Async testing
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Loading...')).not.toBeInTheDocument();
|
|
});
|
|
|
|
// User interactions
|
|
await user.click(screen.getByRole('button'));
|
|
await user.type(screen.getByLabelText(/search/i), 'query');
|
|
|
|
// API integration tests
|
|
const response = await request(app)
|
|
.post('/api/users')
|
|
.send(userData)
|
|
.expect(201);
|
|
```
|