Part 2: Unit Testing with TypeScript
Introduction
What Makes a Good Unit Test?
Example: Order Calculation Service
// src/services/order-calculator.ts
export interface OrderItem {
productId: string;
price: number;
quantity: number;
}
export interface TaxRate {
state: string;
rate: number;
}
export class OrderCalculator {
calculateSubtotal(items: OrderItem[]): number {
return items.reduce((sum, item) => {
return sum + (item.price * item.quantity);
}, 0);
}
calculateTax(subtotal: number, taxRate: TaxRate): number {
return subtotal * taxRate.rate;
}
calculateTotal(items: OrderItem[], taxRate: TaxRate): number {
const subtotal = this.calculateSubtotal(items);
const tax = this.calculateTax(subtotal, taxRate);
return subtotal + tax;
}
applyDiscount(total: number, discountPercent: number): number {
if (discountPercent < 0 || discountPercent > 100) {
throw new Error('Discount must be between 0 and 100');
}
return total * (1 - discountPercent / 100);
}
}Testing Async Code
Example: User Service with Database
Mocking and Stubbing
When to Mock
Example: Testing Time-Dependent Code
Testing Error Handling
Example: Payment Service
Parameterized Tests
Test Helpers and Factories
Test-Driven Development (TDD)
TDD Example: Email Validator
Best Practices from Production
1. Keep Tests Fast
2. Test Edge Cases
3. Use Descriptive Assertions
4. Don't Test Third-Party Code
Common Pitfalls
1. Over-Mocking
2. Brittle Tests
Key Takeaways
What's Next?
Last updated