Official agent skill

Generate Testability Wrappers

by microsoft in microsoft/testfx

Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C.

OfficialMITAuto-check passedBackend & APIs

Install Generate Testability Wrappers

skills CLI
$ npx skills add microsoft/testfx --skill generate-testability-wrappers -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install microsoft/testfx generate-testability-wrappers --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/microsoft/testfx.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/generate-testability-wrappers .claude/skills/generate-testability-wrappers && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
generate-testability-wrappers
GitHub stars
1k
Token cost
~2.2k tokens
SKILL.md length
647 words
Files
1
Skills in repo
44
Repo updated
First seen
Licence
MIT

At a glance

Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C.

  • Works in 6 steps: Determine the abstraction strategy → Generate built-in abstraction adoption… → Generate custom wrappers (Environment,… → …
  • : generate wrapper for static
  • SKILL.md covers When to Use, When Not to Use, Inputs and Workflow, plus 2 more sections
  • Calls dotnet

What it does

Generate Testability Wrappers is an agent skill from microsoft/testfx, published by the product's own GitHub organization. Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C. Produces IFileSystem, IEnvironmentProvider, IConsole, IProcessRunner wrappers, or guides adoption of TimeProvider and IHttpClientFactory. USE FOR: generate wrapper for static, create IFileSystem wrapper, wrap DateTime.Now, make static testable, make class testable, create abstraction for File., generate DI registration, TimeProvider adoption, IHttpClientFactory setup, testability wrapper, mock-friendly interface, mock time…

Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering API design. It works with .NET and C#. The repository describes itself as: This repository holds the source code of Microsoft.Testing.Platform (MTP), a lightweight alternative to VSTest, as well as MSTest adapter and framework. The licence is MIT.

When your agent uses it

  • : generate wrapper for static
  • Create IFileSystem wrapper
  • Wrap DateTime.Now
  • Make static testable

Example prompts

  • “/generate-testability-wrappers”

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Determine the abstraction strategy
  2. Generate built-in abstraction adoption (Time, HTTP)
  3. Generate custom wrappers (Environment, Console, Process)
  4. Generate file system wrapper adoption
  5. Generate ambient context alternative (when DI is not available)
  6. Place generated files

What it can do on your machine

Read from SKILL.md and the folder at commit 44b9dcc. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • dotnet

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Generate Testability Wrappers loads about 2.2k tokens when it runs. Until then it costs about 236 tokens; SKILL.md has 647 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~236
When it runs · the whole SKILL.md, loaded when a task matches
~2.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from microsoft/testfx at commit 44b9dcc, republished under its MIT licence (© microsoft). 647 words, ~2,190 tokens.

Download SKILL.mdSave it as .claude/skills/generate-testability-wrappers/SKILL.md (or your agent's skills folder).
name
generate-testability-wrappers
description
Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C#. Produces IFileSystem, IEnvironmentProvider, IConsole, IProcessRunner wrappers, or guides adoption of TimeProvider and IHttpClientFactory. USE FOR: generate wrapper for static, create IFileSystem wrapper, wrap DateTime.Now, make static testable, make class testable, create abstraction for File.*, generate DI registration, TimeProvider adoption, IHttpClientFactory setup, testability wrapper, mock-friendly interface, mock time in tests, create the right abstraction to mock, how to mock DateTime, test code using File.ReadAllText, what abstraction for Environment, how to make statics injectable, adopt System.IO.Abstractions, make file calls testable. DO NOT USE FOR: detecting statics (use detect-static-dependencies), migrating call sites (use migrate-static-to-wrapper), general interface design not about testability.
license
MIT

Generate Testability Wrappers

Generate wrapper interfaces, default implementations, and DI service registration code for untestable static dependencies. For statics that already have .NET built-in abstractions (TimeProvider, IHttpClientFactory), guide adoption of the built-in. For statics without built-in alternatives, generate custom minimal wrappers.

When to Use

  • After running detect-static-dependencies and identifying which statics to wrap
  • When the user asks to make a class testable by replacing statics with injected abstractions
  • When adopting TimeProvider (.NET 8+) or System.IO.Abstractions
  • When creating a custom wrapper for Environment.*, Console.*, or Process.*

When Not to Use

  • The user wants to find statics first (use detect-static-dependencies)
  • The user wants to bulk-replace call sites (use migrate-static-to-wrapper)
  • The static is already behind an interface
  • The project does not use dependency injection and the user does not want to add it

Inputs

InputRequiredDescription
Static categoryYesWhich category: time, filesystem, environment, network, console, process
Target frameworkYesThe TargetFramework from .csproj (affects which built-in abstractions exist)
DI containerNoWhich DI framework: microsoft (default), autofac, none (ambient context)
NamespaceNoTarget namespace for generated wrapper code

Workflow

Step 1: Determine the abstraction strategy

Based on the category and target framework:

Category.NET 8+.NET 6-7.NET Framework
TimeTimeProvider (built-in)TimeProvider via Microsoft.Bcl.TimeProvider NuGetCustom ISystemClock
File systemSystem.IO.Abstractions (NuGet)SameSame
HTTPIHttpClientFactory (built-in)SameSame
EnvironmentCustom IEnvironmentProviderSameSame
ConsoleCustom IConsoleSameSame
ProcessCustom IProcessRunnerSameSame
Step 2: Generate built-in abstraction adoption (Time, HTTP)
TimeProvider (.NET 8+)

No wrapper code needed — guide the user:

  1. Register in DI:
csharp
builder.Services.AddSingleton(TimeProvider.System);
  1. Inject into classes:
csharp
public class OrderProcessor(TimeProvider timeProvider)
{
    public bool IsExpired(Order order)
        => timeProvider.GetUtcNow() > order.ExpiresAt;
}
  1. Test with FakeTimeProvider:
csharp
// Requires Microsoft.Extensions.TimeProvider.Testing NuGet
var fakeTime = new FakeTimeProvider(new DateTimeOffset(2026, 1, 15, 0, 0, 0, TimeSpan.Zero));
var processor = new OrderProcessor(fakeTime);
fakeTime.Advance(TimeSpan.FromDays(1));
Assert.True(processor.IsExpired(order));
TimeProvider (pre-.NET 8)

Guide: install Microsoft.Bcl.TimeProvider NuGet. Same API as above.

IHttpClientFactory

No wrapper code needed — register typed clients via builder.Services.AddHttpClient<MyService>() and inject HttpClient directly into the class constructor.

Step 3: Generate custom wrappers (Environment, Console, Process)

For categories without built-in abstractions, follow this template:

Interface — define the minimal surface

Only include methods that were actually detected in the codebase. Do NOT generate a wrapper for every possible member — wrap only what is used.

csharp
namespace <Namespace>;

/// <summary>
/// Abstraction over <static class> for testability. 
/// </summary>
public interface I<WrapperName>
{
    // One method per detected static call
    <return type> <MethodName>(<parameters>);
}
Default implementation — delegate to the real static
csharp
namespace <Namespace>;

/// <summary>
/// Default implementation that delegates to <static class>.
/// </summary>
public sealed class <WrapperName> : I<WrapperName>
{
    public <return type> <MethodName>(<parameters>)
        => <StaticClass>.<Method>(<arguments>);
}
DI registration
csharp
// In Program.cs or Startup.cs:
builder.Services.AddSingleton<I<WrapperName>, <WrapperName>>();
Step 4: Generate file system wrapper adoption

Prefer the established System.IO.Abstractions NuGet package over custom wrappers:

  1. Install the package:
dotnet add package System.IO.Abstractions
  1. Register in DI:
csharp
builder.Services.AddSingleton<IFileSystem, FileSystem>();
  1. Inject IFileSystem into classes:
csharp
public class ConfigLoader(IFileSystem fileSystem)
{
    public string LoadConfig(string path)
        => fileSystem.File.ReadAllText(path);
}
  1. Test with MockFileSystem:
dotnet add <TestProject> package System.IO.Abstractions.TestingHelpers
csharp
var mockFs = new MockFileSystem(new Dictionary<string, MockFileData>
{
    { "/config.json", new MockFileData("{\"key\": \"value\"}") }
});
var loader = new ConfigLoader(mockFs);
Assert.Equal("{\"key\": \"value\"}", loader.LoadConfig("/config.json"));
Show full SKILL.md (268 more words)Show less
Step 5: Generate ambient context alternative (when DI is not available)

If the codebase does not use DI (e.g., old console app, library code), offer the ambient context pattern:

csharp
public static class Clock
{
    private static readonly AsyncLocal<Func<DateTimeOffset>?> s_override = new();
    public static DateTimeOffset UtcNow
        => s_override.Value?.Invoke() ?? TimeProvider.System.GetUtcNow();

    public static IDisposable Override(DateTimeOffset fixedTime)
    {
        s_override.Value = () => fixedTime;
        return new Scope();
    }
    private sealed class Scope : IDisposable
    {
        public void Dispose() => s_override.Value = null;
    }
}

Key trade-offs: AsyncLocal<T> ensures parallel tests don't interfere; production cost is one null check per call; the static readonly field is essentially free.

Step 6: Place generated files

Generate files following the project's existing conventions:

  • If there is an Abstractions/ or Interfaces/ folder, place the interface there
  • If there is an Infrastructure/ or Services/ folder, place the implementation there
  • Otherwise, create files next to the code that uses the static

Always generate:

  1. The interface file (or adoption instructions for built-in abstractions)
  2. The default implementation file
  3. The DI registration snippet (as a code comment at the bottom of the implementation, or as separate instructions)

Validation

  • Generated interface only wraps statics that were actually detected (not speculative)
  • Default implementation delegates to the real static with no behavior changes
  • DI registration uses AddSingleton for stateless wrappers, AddTransient for stateful ones
  • NuGet packages are recommended where established libraries exist (System.IO.Abstractions, etc.)
  • For .NET 8+, TimeProvider is recommended over custom ISystemClock
  • Ambient context pattern includes AsyncLocal<T>, scoped disposal, and trade-off explanation

Common Pitfalls

PitfallSolution
Wrapping ALL members of a static classOnly wrap methods actually called in the codebase
Custom time wrapper on .NET 8+Use built-in TimeProvider instead
Custom file system wrapperPrefer System.IO.Abstractions NuGet — battle-tested, complete
Registering scoped when singleton sufficesStateless wrappers should be AddSingleton
Forgetting test helper packagesMicrosoft.Extensions.TimeProvider.Testing for time, System.IO.Abstractions.TestingHelpers for filesystem
Ambient context without AsyncLocalNon-async [ThreadStatic] breaks with async/await — always use AsyncLocal<T>

© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/generate-testability-wrappers of microsoft/testfx.

Open the folder on GitHubat commit 44b9dcc

Compare with similar skills

Generate Testability Wrappers next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Generate Testability Wrappers compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Generate Testability Wrappers this skillmicrosoft/testfx1k—~2.2kAutomated safety check: PassMIT
.NET API Compatibility DesignAaronontheweb/dotnet-skills1.2k2 repos~2.7kAutomated safety check: PassMIT
Csharp Nullable Reference TypesAaronontheweb/dotnet-skills1.2k1 repos~2.9kAutomated safety check: PassMIT
Generate Testability Wrappersdotnet/skills5.6k1 repos~3.9kAutomated safety check: PassMIT
Csharp Dotnetericrisco/rsc-harness156—~3.3kAutomated safety check: PassMIT
Aa Batching PaymastersNethereum/Nethereum2.3k—~1.5kAutomated safety check: PassMIT

Similar skills

  • .NET API Compatibility Design

    Aaronontheweb/dotnet-skills

    Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely.

    1.2k GitHub starsUsed in 2 repos~2.7k tokens
    Backend & APIsAuto-check passed
  • Csharp Nullable Reference Types

    Aaronontheweb/dotnet-skills

    Guidelines for introducing and using nullable reference types (NRT) and System.Diagnostics.CodeAnalysis nullable attributes in C / .NET codebases.

    1.2k GitHub starsUsed in 1 repo~2.9k tokens
    Backend & APIsAuto-check passed
  • Official

    DO NOT USE when the target already consumes an injected interface or built-in abstraction such as IFileSystem or TimeProvider, even if the request says "generate a wrapper"; no new wrapper is needed.

    5.6k GitHub starsUsed in 1 repo~3.9k tokens
    Backend & APIsAuto-check passed
  • Csharp Dotnet

    ericrisco/rsc-harness

    A skill your agent uses when writing, reviewing, testing, or shipping C / .NET code — ASP.NET Core APIs (minimal APIs vs controllers), EF Core data access, async correctness, solution layout in…

    156 GitHub stars~3.3k tokensUpdated today
    Backend & APIsAuto-check passed
  • Aa Batching Paymasters

    Nethereum/Nethereum

    Help users batch multiple calls into a single UserOperation and sponsor gas with paymasters using Nethereum Account Abstraction.

    2.3k GitHub stars~1.5k tokensUpdated 2 days ago
    Backend & APIsAuto-check passed
  • Tsp Csharp

    querylenshq/ef-querylens

    Comprehensive C and .NET development skill for TSP projects.

    225 GitHub stars~1.3k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed

More from microsoft/testfx

All 44 skills in this repo
  • Official

    Guide for organizing MSBuild infrastructure with Directory.Build.props, Directory.Build.targets, Directory.Packages.props, and Directory.Build.rsp.

    1k GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Binlog Failure Analysis

    microsoft/testfx

    Official

    Analyze MSBuild binary logs to diagnose build failures. An agent skill from microsoft/testfx.

    1k GitHub starsUsed in 3 repos~730 tokens
    Auto-check passed
  • Coverage Analysis

    microsoft/testfx

    Official

    Project-wide code coverage and CRAP (Change Risk Anti-Patterns) score analysis for .NET projects.

    1k GitHub stars~7.3k tokensUpdated today
    Auto-check passed
  • Incremental Build

    microsoft/testfx

    Official

    Guide for optimizing MSBuild incremental builds. An agent skill from microsoft/testfx.

    1k GitHub starsUsed in 3 repos~3.7k tokens
    Auto-check passed
  • Msbuild Modernization

    microsoft/testfx

    Official

    Guide for modernizing and migrating MSBuild project files to SDK-style format.

    1k GitHub starsUsed in 3 repos~4.3k tokens
    Auto-check passed
  • Msbuild Antipatterns

    microsoft/testfx

    Official

    Catalog of MSBuild anti-patterns with detection rules and fix recipes.

    1k GitHub stars~4.5k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Generate Testability Wrappers

What does Generate Testability Wrappers do?

Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C. Generate Testability Wrappers is an agent skill from microsoft/testfx, published by the product's own GitHub organization. Generate wrapper interfaces and DI registration for hard-to-test static dependencies in C.

When should I use Generate Testability Wrappers?

Generate Testability Wrappers fits situations like: : generate wrapper for static; create IFileSystem wrapper; wrap DateTime.Now; make static testable.

How do I install Generate Testability Wrappers in Claude Code?

Run `npx skills add microsoft/testfx --skill generate-testability-wrappers -a claude-code`. Or copy the skill folder (.agents/skills/generate-testability-wrappers in microsoft/testfx) into .claude/skills/generate-testability-wrappers in your project. Claude Code loads it when a task matches its description.

How do I install Generate Testability Wrappers in Codex?

Run `npx skills add microsoft/testfx --skill generate-testability-wrappers -a codex`. Or copy the skill folder (.agents/skills/generate-testability-wrappers in microsoft/testfx) into .agents/skills/generate-testability-wrappers in your project. Codex loads it when a task matches its description.

Can I use Generate Testability Wrappers in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/testfx --skill generate-testability-wrappers -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/generate-testability-wrappers, .gemini/skills/generate-testability-wrappers, .github/skills/generate-testability-wrappers and .opencode/skills/generate-testability-wrappers in your project.

What does Generate Testability Wrappers need to run?

Going by SKILL.md and its folder, Generate Testability Wrappers needs the command-line tools its instructions call (dotnet).

Does Generate Testability Wrappers access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Generate Testability Wrappers safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Generate Testability Wrappers use?

Generate Testability Wrappers is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Generate Testability Wrappers use?

About 2.2k tokens (SKILL.md is roughly 8.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Generate Testability Wrappers?

Skills that share tags, products or a category with Generate Testability Wrappers: .NET API Compatibility Design (Aaronontheweb/dotnet-skills, 1.2k stars), Csharp Nullable Reference Types (Aaronontheweb/dotnet-skills, 1.2k stars), Generate Testability Wrappers (dotnet/skills, 5.6k stars) and Csharp Dotnet (ericrisco/rsc-harness, 156 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Generate Testability Wrappers?

microsoft (a GitHub organization, an official publisher) maintains it in microsoft/testfx, which has 1,047 GitHub stars. The repository holds 44 skills in this directory. The repository was last updated on October 7, 2026.

Source: microsoft/testfx on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.