CtrlK
BlogDocsLog inGet started
Tessl Logo

haletothewood/behavioural-tdd

Execute a strict Red-Green-Refactor TDD cycle — one requirement at a time — in any language or framework.

97

1.11x

Quality

100%

Does it follow best practices?

Impact

94%

1.11x

Average score across 5 eval scenarios

Overview
Skills
Evals
Files

mocking.mdreferences/

Mocking Guidelines

Mock at system boundaries only

Mock theseNever mock these
External APIs (payment, email, SMS)Your own classes or modules
Databases (or use a test DB instead)Internal collaborators
Time and randomnessAnything you control and can test directly
File system (when impractical to use real files)Private methods

Use dependency injection

Pass external dependencies in rather than creating them internally. This makes the seam explicit and mockable without touching internals.

// Testable — dependency is injected
function processPayment(order: Order, paymentClient: PaymentClient) {
  return paymentClient.charge(order.total);
}

// Hard to mock — dependency created internally
function processPayment(order: Order) {
  const client = new StripeClient(process.env.STRIPE_KEY);
  return client.charge(order.total);
}

Prefer SDK-style interfaces over generic fetchers

Design boundary interfaces as named operations rather than a single generic call. Each operation is independently mockable with no conditional logic.

// GOOD: each operation is independently mockable
const api = {
  getUser: (id: string) => fetch(`/users/${id}`),
  getOrders: (userId: string) => fetch(`/users/${userId}/orders`),
  createOrder: (data: OrderData) =>
    fetch('/orders', { method: 'POST', body: JSON.stringify(data) }),
};

// BAD: mocking requires conditional logic inside the mock
const api = {
  fetch: (endpoint: string, options?: RequestInit) => fetch(endpoint, options),
};

Design interfaces that return results, not side effects

Functions that return values are easier to test than functions that mutate state as a side effect.

// Testable — assert on the return value
function calculateDiscount(cart: Cart): Discount {
  return { amount: cart.total * 0.1 };
}

// Harder to test — must inspect mutated state
function applyDiscount(cart: Cart): void {
  cart.total -= cart.total * 0.1;
}

Install with Tessl CLI

npx tessl i haletothewood/behavioural-tdd@1.8.0

SKILL.md

tile.json