Setting up tests for new code covering unit tests, integration tests, and test organization
Guidance for writing effective tests, organizing test files, and establishing good testing practices.
What: Test individual functions/classes in isolation When: Pure logic, utilities, business rules Speed: Fast (milliseconds) Dependencies: Mock external dependencies
describe('calculateDiscount', () => {
it('applies 10% discount for premium users', () => {
const result = calculateDiscount(100, 'premium')
expect(result).toBe(90)
})
it('returns original price for regular users', () => {
const result = calculateDiscount(100, 'regular')
expect(result).toBe(100)
})
})
What: Test multiple components working together When: API endpoints, database operations, service interactions Speed: Slower (seconds) Dependencies: Use real dependencies or test doubles
describe('POST /api/users', () => {
it('creates user and returns 201', async () => {
const response = await request(app)
.post('/api/users')
.send({ name: 'Test User', email: 'test@example.com' })
expect(response.status).toBe(201)
expect(response.body.user).toMatchObject({
name: 'Test User',
email: 'test@example.com'
})
})
})
What: Test complete user workflows When: Critical user paths, full stack verification Speed: Slowest (seconds to minutes)
your-project/
βββ src/
β βββ utils.js
β βββ api/users.js
βββ tests/
β βββ unit/
β β βββ utils.test.js
β βββ integration/
β β βββ api/users.test.js
β βββ e2e/
β βββ checkout.spec.js
test('descriptive test name', () => {
// Arrange - Set up test data
const user = { id: 1, name: 'Test' }
// Act - Execute the code
const result = service.formatUser(user)
// Assert - Verify the results
expect(result).toBe('User: Test')
})
// Bad
test('it works', ...)
test('test user', ...)
// Good
test('returns 404 when user not found', ...)
test('calculates total including tax', ...)
Separate tests for each behavior, not one giant test.
describe('divide', () => {
it('divides two positive numbers', () => {
expect(divide(10, 2)).toBe(5)
})
it('throws when dividing by zero', () => {
expect(() => divide(10, 0)).toThrow('Division by zero')
})
})
Mock:
Don't mock:
Good: High coverage with meaningful assertions Bad: High coverage with weak assertions
When writing tests: