# Testability Obstacle

MUST USE for C#/.NET deterministic tests that require the smallest production seam for...

- Repository: https://github.com/managedcode/dotnet-skills (500 stars)
- Category: Testing
- License: MIT
- Last updated: 2026-10-29
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add managedcode/dotnet-skills --skill testability-obstacle -g -a claude-code -y`
Codex: `npx skills add managedcode/dotnet-skills --skill testability-obstacle -g -a codex -y`
Cursor: `npx skills add managedcode/dotnet-skills --skill testability-obstacle -g -a cursor -y`
Gemini CLI: `npx skills add managedcode/dotnet-skills --skill testability-obstacle -g -a gemini-cli -y`

## Description

MUST USE for C#/.NET deterministic tests that require the smallest production seam for DateTime/Task.Delay/File/Environment/Guid/Random, static API preservation, nested/parallel overrides, or no real I/O. USE ONLY when the target workspace contains C# source plus a .csproj or .sln. DO NOT USE for audits, bulk migration, code that already has an injectable seam, or an explicit migration to a user-named existing abstraction (migrate-static-to-wrapper). Use instead of general test generation when the requested test is impossible without a production edit and seam selection is still open.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Resolve a Testability Obstacle

Introduce the smallest behavior-preserving seam needed to test a specific C#
behavior, then add deterministic tests that prove both the behavior and the seam.
The production edit is a means to the requested test, not an invitation to
redesign adjacent code.

## When to Use

- A requested test would otherwise read/write the real filesystem.
- Behavior depends on the current time, delay, random value, environment, console,
  process, or another ambient dependency.
- The user explicitly permits or requests a safe production seam.
- Existing tests cannot control a dependency without process-global mutation.

## When Not to Use

- The dependency is already injected or passed as an argument. Write tests with
  a fake through the existing seam using `code-testing`.
- The user wants a repository-wide testability audit. Use
  `detect-static-dependencies`.
- The user wants wrappers generated but not call sites/tests changed. Use
  `generate-testability-wrappers`.
- The user requests a broad mechanical migration. Use
  `migrate-static-to-wrapper`, then generate tests separately.
- The user already selected an existing replacement such as `TimeProvider` or
  `IFileSystem` and asks to migrate call sites to it. Use
  `migrate-static-to-wrapper`, which also updates affected tests.
- The code is not C#/.NET.

## Inputs

| Input | Required | Description |
|-------|----------|-------------|
| Behavior to test | Yes | The method/workflow and expected observable behavior |
| Target scope | No | Discover the narrowest relevant file/project when omitted |
| Allowed production changes | No | Default to the minimum internal/constructor seam |

## Workflow

### Step 1: Prove the obstacle

Read the target production path and its existing tests. Identify the exact ambient
operation preventing a deterministic test and the behavior that must remain
unchanged. Do not run a repository-wide static scan for a single-class request.

The rest: https://github.com/managedcode/dotnet-skills/blob/HEAD/catalog/Testing/Official-DotNet-Test/skills/testability-obstacle/SKILL.md
