Skip to content
Development
Skill

/nw-tdd-methodology-test-doubles

Choosing and building a test double - Meszaros taxonomy, classical-vs-mockist verification, the mock-only-at-port-boundaries policy, and the contract that every InMemory double must validate inputs like the real adapter

From plugin
nwave
635183 skills37 agents

Claude Code

$ npx -y skills add nWave-ai/nWave --skill nw-tdd-methodology-test-doubles --agent claude-code

SKILL.md

nw-tdd-methodology-test-doubles.SKILL.md
name: nw-tdd-methodology-test-doubles
description: Choosing and building a test double - Meszaros taxonomy, classical-vs-mockist verification, the mock-only-at-port-boundaries policy, and the contract that every InMemory double must validate inputs like the real adapter
user-invocable: false
disable-model-invocation: true

Test Doubles — Taxonomy, Policy, Input-Validation Contract

**Trigger**: choosing a test double or verification style — what to mock, which double type, classical-vs-mockist, and the input-validation contract every InMemory double must satisfy.

Classical vs Mockist Verification

Classical TDD: real objects | state verification | less coupled to implementation | survives refactoring better. Mockist TDD: mocks for objects with behavior | behavior verification | lighter setup | more coupled to impl. Best practice: combine strategically. Behavior verification at layer boundaries, state verification within layers.

Test Doubles Taxonomy (Meszaros)

  • Dummy: passed but never used
  • Fake: working impl with shortcuts (in-memory DB)
  • Stub: predefined answers
  • Spy: stub that records interactions
  • Mock: pre-programmed with expectations for behavior verification

Choose type by need: mock for interaction design | stub when don't care about interaction | fake for integration bridge.

Test Doubles Policy

Acceptable (port boundaries only):

  • `Mock<IPaymentGateway>` - external payment service port
  • `Mock<IEmailService>` - external email provider port
  • `InMemoryUserRepository` - fake for fast tests (implements IUserRepository port)

Do not mock inside the hexagon:

  • Domain entities (Order, Customer) - use real objects
  • Value objects (Money, Email) - cheap to create, deterministic
  • Application services (OrderProcessor) - use real with mocked ports
  • Domain services (PricingService) - use real objects

Integration Test Contract: Test Doubles Must Validate Inputs

Every InMemory test double MUST enforce the same input preconditions as the real adapter. A test double that accepts inputs the real adapter would reject creates invisible wiring bugs that only surface in production.

**The rule**: if the real adapter crashes on an input, the test double must also fail on that input.

**What to validate in every test double:**

  • Required parameters are not None
  • Required string fields are not empty
  • Numeric fields are within valid ranges (turns > 0, timeout > 0, budget >= 0)
  • Enum fields contain valid values
  • Complex objects have required nested fields populated

**Why**: dogfood empirics found 3 wiring bugs that 96 acceptance tests missed — because InMemoryVendorAdapter accepted None config, empty prompt file, and wrong field names. The real adapter crashed on all 3. The tests were green but the system was broken.

**Example**:

# WRONG — too permissive, hides wiring bugs
class InMemoryVendorAdapter:
    def dispatch(self, config):
        return Success(self._canned_result)  # accepts anything

# CORRECT — validates like the real adapter
class InMemoryVendorAdapter:
    def dispatch(self, config):
        assert config is not None, "PhaseDispatchConfig required"
        assert config.assembled_prompt_file, "Prompt file must be set"
        assert config.max_turns > 0, "max_turns must be positive"
        return Success(self._canned_result)

This is not optional. A test double without input validation is a test double that lies.

Read more
@nwave-ai
Ships withnwave

nWave supplies specialist roles and a host-led delivery workflow for software teams.

635183 skills37 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
635
Star history of nWave-ai/nWave on GitHub, a chart by star-history.com

Other skills on nwave.

nw-ab-agent-template

nw-ab-agent-template

KNOWLEDGE — the canonical agent-spec template (frontmatter + body skeleton). Reference loaded by the create/migrate procedures;…

@nwave-ai@nwave-aiInstall Skill
nw-ab-anti-patterns

nw-ab-anti-patterns

KNOWLEDGE — agent/skill/command anti-pattern catalog with fixes. Reference scanned by validate-spec; no sequence.

@nwave-ai@nwave-aiInstall Skill
nw-ab-create-agent

nw-ab-create-agent

PROCEDURE — create a NEW agent via the 5-phase workflow (ANALYZE→DESIGN→CREATE→VALIDATE→REFINE). Trigger: build a new AI agent.…

@nwave-ai@nwave-aiInstall Skill
nw-ab-examples

nw-ab-examples

KNOWLEDGE — canonical worked examples for agent creation, migration, and command optimization. Reference for the relevant…

@nwave-ai@nwave-aiInstall Skill
nw-ab-house-style

nw-ab-house-style

KNOWLEDGE — caveman-native authoring house style + by-construction guarantees (Reasoning Mandate injection, measured-gain…

@nwave-ai@nwave-aiInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills13d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react4d252k
@facebook@facebookInstall Skill

Questions about nw-tdd-methodology-test-doubles.

Which coding agents can use nw-tdd-methodology-test-doubles?
nw-tdd-methodology-test-doubles installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.