返回 AiToEarn
tests.md
1 # Good and Bad Tests
2
3 ## Good Tests
4
5 **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
7 ```typescript
8 // GOOD: Tests observable behavior
9 test("user can checkout with valid cart", async () => {
10 const cart = createCart();
11 cart.add(product);
12 const result = await checkout(cart, paymentMethod);
13 expect(result.status).toBe("confirmed");
14 });
15 ```
16
17 Characteristics:
18
19 - Tests behavior users/callers care about
20 - Uses public API only
21 - Survives internal refactors
22 - Describes WHAT, not HOW
23 - One logical assertion per test
24
25 ## Bad Tests
26
27 **Implementation-detail tests**: Coupled to internal structure.
28
29 ```typescript
30 // BAD: Tests implementation details
31 test("checkout calls paymentService.process", async () => {
32 const mockPayment = jest.mock(paymentService);
33 await checkout(cart, payment);
34 expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35 });
36 ```
37
38 Red flags:
39
40 - Mocking internal collaborators
41 - Testing private methods
42 - Asserting on call counts/order
43 - Test breaks when refactoring without behavior change
44 - Test name describes HOW not WHAT
45 - Verifying through external means instead of interface
46
47 ```typescript
48 // BAD: Bypasses interface to verify
49 test("createUser saves to database", async () => {
50 await createUser({ name: "Alice" });
51 const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52 expect(row).toBeDefined();
53 });
54
55 // GOOD: Verifies through interface
56 test("createUser makes user retrievable", async () => {
57 const user = await createUser({ name: "Alice" });
58 const retrieved = await getUser(user.id);
59 expect(retrieved.name).toBe("Alice");
60 });
61 ```
62
62 lines MARKDOWN