返回 AiToEarn
mocking.md
1 # When to Mock
2
3 Mock at **system boundaries** only:
4
5 - External APIs (payment, email, etc.)
6 - Databases (sometimes - prefer test DB)
7 - Time/randomness
8 - File system (sometimes)
9
10 Don't mock:
11
12 - Your own classes/modules
13 - Internal collaborators
14 - Anything you control
15
16 ## Designing for Mockability
17
18 At system boundaries, design interfaces that are easy to mock:
19
20 **1. Use dependency injection**
21
22 Pass external dependencies in rather than creating them internally:
23
24 ```typescript
25 // Easy to mock
26 function processPayment(order, paymentClient) {
27 return paymentClient.charge(order.total);
28 }
29
30 // Hard to mock
31 function processPayment(order) {
32 const client = new StripeClient(process.env.STRIPE_KEY);
33 return client.charge(order.total);
34 }
35 ```
36
37 **2. Prefer SDK-style interfaces over generic fetchers**
38
39 Create specific functions for each external operation instead of one generic function with conditional logic:
40
41 ```typescript
42 // GOOD: Each function is independently mockable
43 const api = {
44 getUser: (id) => fetch(`/users/${id}`),
45 getOrders: (userId) => fetch(`/users/${userId}/orders`),
46 createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47 };
48
49 // BAD: Mocking requires conditional logic inside the mock
50 const api = {
51 fetch: (endpoint, options) => fetch(endpoint, options),
52 };
53 ```
54
55 The SDK approach means:
56 - Each mock returns one specific shape
57 - No conditional logic in test setup
58 - Easier to see which endpoints a test exercises
59 - Type safety per endpoint
60
60 lines MARKDOWN