Official agent skill

Migrate Static To Wrapper

by microsoft in microsoft/testfx

Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace).

OfficialMITAuto-check passedDevelopment

Install Migrate Static To Wrapper

skills CLI
$ npx skills add microsoft/testfx --skill migrate-static-to-wrapper -a claude-code

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

GitHub CLI
$ gh skill install microsoft/testfx migrate-static-to-wrapper --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/migrate-static-to-wrapper .claude/skills/migrate-static-to-wrapper && 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
migrate-static-to-wrapper
GitHub stars
1k
Token cost
~2.1k tokens
SKILL.md length
711 words
Files
1
Skills in repo
44
Repo updated
First seen
Licence
MIT

At a glance

Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace).

  • Works in 7 steps: Verify prerequisites → Plan the migration for each file → Add constructor injection → …
  • : replace DateTime.UtcNow with TimeProvider
  • SKILL.md covers When to Use, When Not to Use, Inputs and Workflow, plus 2 more sections
  • Calls dotnet

What it does

Migrate Static To Wrapper is an agent skill from microsoft/testfx, published by the product's own GitHub organization. Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace). Performs codemod-style bulk replacement of DateTime.UtcNow to TimeProvider.GetUtcNow(), File.ReadAllText to IFileSystem, and similar transformations. Adds constructor injection parameters and updates DI registration. USE FOR: replace DateTime.UtcNow with TimeProvider, replace DateTime.Now with TimeProvider, migrate static calls to wrapper, bulk replace File. with…

Its SKILL.md is about 2.1k 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 Development, covering Code migrations. 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

  • : replace DateTime.UtcNow with TimeProvider
  • Replace DateTime.Now with TimeProvider
  • Migrate static calls to wrapper
  • Bulk replace File

Example prompts

  • “/migrate-static-to-wrapper”

Workflow steps

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

  1. Verify prerequisites
  2. Plan the migration for each file
  3. Add constructor injection
  4. Replace call sites
  5. Update affected test files
  6. Build verification
  7. Report changes

What it can do on your machine

Read from SKILL.md and the folder at commit 7c7d590. 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

Migrate Static To Wrapper loads about 2.1k tokens when it runs. Until then it costs about 258 tokens; SKILL.md has 711 words of instructions outside code blocks.

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

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 7c7d590, republished under its MIT licence (© microsoft). 711 words, ~2,068 tokens.

Download SKILL.mdSave it as .claude/skills/migrate-static-to-wrapper/SKILL.md (or your agent's skills folder).
name
migrate-static-to-wrapper
description
Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace). Performs codemod-style bulk replacement of DateTime.UtcNow to TimeProvider.GetUtcNow(), File.ReadAllText to IFileSystem, and similar transformations. Adds constructor injection parameters and updates DI registration. USE FOR: replace DateTime.UtcNow with TimeProvider, replace DateTime.Now with TimeProvider, migrate static calls to wrapper, bulk replace File.* with IFileSystem, codemod static to injectable, add constructor injection for time provider, mechanical migration of statics, refactor DateTime to TimeProvider, swap static for injected dependency, convert static calls to use abstraction, replace statics in a class, migrate one file to TimeProvider, scoped migration, update call sites. DO NOT USE FOR: detecting statics (use detect-static-dependencies), generating wrappers (use generate-testability-wrappers), migrating between test frameworks.
license
MIT

Migrate Static to Wrapper

Perform mechanical, codemod-style replacement of static dependency call sites with calls to injected wrapper interfaces or built-in abstractions. Operates on a bounded scope (single file, project, or namespace) so migrations can be done incrementally.

When to Use

  • After wrappers have been generated (via generate-testability-wrappers) or built-in abstractions identified
  • Migrating DateTime.UtcNow → TimeProvider.GetUtcNow() across a project
  • Migrating File.* → IFileSystem.File.* across a namespace
  • Adding constructor injection for the new abstraction to affected classes
  • Incremental migration: one project or namespace at a time

When Not to Use

  • No wrapper or abstraction exists yet (use generate-testability-wrappers first)
  • The user wants to detect statics, not migrate them (use detect-static-dependencies)
  • The code does not use dependency injection and the user hasn't chosen ambient context
  • Migrating between test frameworks (use the appropriate migration skill)

Inputs

InputRequiredDescription
Static patternYesWhat to replace (e.g., DateTime.UtcNow, File.ReadAllText)
Replacement abstractionYesWhat to use instead (e.g., TimeProvider, IFileSystem)
ScopeYesFile path, project (.csproj), namespace, or directory to migrate
Injection strategyNoconstructor (default), primary-constructor, or ambient

Workflow

Step 1: Verify prerequisites

Before modifying any code:

  1. Confirm the wrapper/abstraction exists: Check that the interface or built-in abstraction is available in the project. For TimeProvider, verify the target framework is .NET 8+ or Microsoft.Bcl.TimeProvider is referenced. For System.IO.Abstractions, verify the NuGet package is referenced.

  2. Confirm DI registration exists: Check Program.cs or Startup.cs for the service registration. If missing, add it before proceeding.

  3. Identify all files in scope: List the .cs files that will be modified. Exclude test projects, obj/, bin/, and generated code.

Step 2: Plan the migration for each file

For each file containing the static pattern, determine:

  1. Which class(es) contain the call sites — identify the class declarations
  2. Whether the class already has the dependency injected — check constructors for existing TimeProvider, IFileSystem, etc. parameters
  3. The replacement expression for each call site
Replacement mapping
CategoryOriginalDI replacement
TimeDateTime.Now_timeProvider.GetLocalNow().DateTime
TimeDateTime.UtcNow_timeProvider.GetUtcNow().DateTime
TimeDateTime.Today_timeProvider.GetLocalNow().Date
TimeDateTimeOffset.UtcNow_timeProvider.GetUtcNow()
FileFile.ReadAllText(path)_fileSystem.File.ReadAllText(path)
FileFile.WriteAllText(path, text)_fileSystem.File.WriteAllText(path, text)
FileFile.Exists(path)_fileSystem.File.Exists(path)
FileDirectory.Exists(path)_fileSystem.Directory.Exists(path)
EnvEnvironment.GetEnvironmentVariable(name)_env.GetEnvironmentVariable(name)
ConsoleConsole.WriteLine(msg)_console.WriteLine(msg)
ProcessProcess.Start(info)_processRunner.Start(info)

Apply the same pattern for other members in each category.

Step 3: Add constructor injection

Add the new dependency following the class's existing pattern:

  • Primary constructor (C# 12+): Add parameter to primary constructor: public class OrderProcessor(ILogger<OrderProcessor> logger, TimeProvider timeProvider)
  • Traditional constructor: Add private readonly field + constructor parameter, matching the existing field naming convention (_camelCase or m_camelCase)
Show full SKILL.md (302 more words)Show less
Step 4: Replace call sites

Perform each replacement mechanically. For each call site:

  1. Replace the static call with the wrapper call
  2. Preserve the surrounding code structure (whitespace, comments, chaining)
  3. Add required using directives if not already present
Adding using directives
AbstractionUsing directive
TimeProviderNone (in System namespace)
IFileSystemusing System.IO.Abstractions;
IHttpClientFactoryusing System.Net.Http; (usually already present)
Custom wrappersusing <wrapper namespace>;
Step 5: Update affected test files

If test files exist for the migrated classes:

  1. Update constructor calls — add the new parameter to test class instantiation
  2. Use test doubles:
    • TimeProvider → new FakeTimeProvider() from Microsoft.Extensions.TimeProvider.Testing
    • IFileSystem → new MockFileSystem() from System.IO.Abstractions.TestingHelpers
    • Custom wrappers → new Mock<IWrapperName>() or hand-rolled fake
Step 6: Build verification

After all changes in the current scope:

bash
dotnet build <project.csproj>

If the build fails:

  • Missing using: Add the required using directive
  • Missing NuGet package: Run dotnet add package <name>
  • Constructor mismatch in tests: Update test instantiation (Step 5)
  • Ambiguous call: Fully qualify the wrapper call
Step 7: Report changes

Summarize what was done:

## Migration Summary

**Pattern**: DateTime.UtcNow → TimeProvider.GetUtcNow()
**Scope**: MyProject/Services/

### Files Modified (production)
| File | Call Sites Replaced | Injection Added |
|------|--------------------:|:----------------|
| OrderProcessor.cs | 3 | Yes (constructor) |
| NotificationService.cs | 1 | Yes (primary ctor) |

### Files Modified (tests)
| File | Change |
|------|--------|
| OrderProcessorTests.cs | Added FakeTimeProvider parameter |

### Remaining (out of scope)
- MyProject/Legacy/ — 8 call sites not migrated (different namespace)

Validation

  • All call sites in scope were replaced (none missed)
  • Constructor injection added to all affected classes
  • Field naming follows existing class conventions
  • Required using directives added
  • Required NuGet packages referenced
  • Build succeeds after migration
  • Test files updated with appropriate test doubles
  • No behavioral changes introduced (wrapper delegates directly to the static)

Common Pitfalls

PitfallSolution
Replacing statics in test codeOnly replace in production code; tests should use fakes/mocks
Breaking static classesStatic classes can't have constructors — use ambient context for these
Missing FakeTimeProvider NuGetAdd Microsoft.Extensions.TimeProvider.Testing to test project
Replacing in expression-bodied members without updating return typeDateTime → DateTimeOffset when using TimeProvider.GetUtcNow() — verify type compatibility
Migrating too much at onceStick to the defined scope — one project or namespace per run
Forgetting DI registrationAlways verify Program.cs/Startup.cs has the registration before replacing call sites

© 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/migrate-static-to-wrapper of microsoft/testfx.

Open the folder on GitHubat commit 7c7d590

Compare with similar skills

Migrate Static To Wrapper 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.

Migrate Static To Wrapper compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Migrate Static To Wrapper this skillmicrosoft/testfx1k—~2.1kAutomated safety check: PassMIT
Migrate Core Code to Submodulestinyhumansai/openhuman42k—~2.6kAutomated safety check: PassGPL-3.0
Migrate Internal Package into GhostTryGhost/Ghost55k—~3.8kAutomated safety check: PassMIT
Next Cache Components Adoptionvercel/next.js143k6 repos~8.3kAutomated safety check: PassMIT
Deprecate R Functions and Argumentstidyverse/dplyr5.1k1 repos~1.2kAutomated safety check: PassCustom licence
Rust Path Typesopeninterpreter/openinterpreter69k2 repos~605Automated safety check: PassApache-2.0

Similar skills

  • Migrate Core Code to Submodules

    tinyhumansai/openhuman

    Plans and carries out moving non-host-specific code and its tests from the OpenHuman core into vendored tiny submodule libraries, then releases the submodule and re-pins the host.

    42k GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.

    55k GitHub stars~3.8k tokensUpdated today
    DevelopmentAuto-check passed
  • Official

    Turn on Cache Components in a Next.js app and resolve the blocking routes it surfaces.

    143k GitHub starsUsed in 6 repos~8.3k tokens
    DevelopmentAuto-check passed
  • Walks through deprecating an R function or argument in a package: lifecycle warning, silenced tests, a new snapshot test, documentation badge and NEWS entry.

    5.1k GitHub starsUsed in 1 repo~1.2k tokens
    DevelopmentAuto-check passed
  • Rust Path Types

    openinterpreter/openinterpreter

    Rules for choosing Rust types for filesystem paths in new Codex code, covering protocol types, internal use and model tool arguments.

    69k GitHub starsUsed in 2 repos~605 tokens
    DevelopmentAuto-check passed
  • ast-grep Structural Search

    code-yeongyu/oh-my-openagent

    Searches and rewrites code by syntax-tree shape across 25 languages with ast-grep, for codemods, structural queries and YAML lint rules, using a Python wrapper script.

    70k GitHub stars~3.3k tokensUpdated today
    DevelopmentAuto-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

Categories

Questions about Migrate Static To Wrapper

What does Migrate Static To Wrapper do?

Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace). Migrate Static To Wrapper is an agent skill from microsoft/testfx, published by the product's own GitHub organization. Mechanically replace static dependency call sites with wrapper or built-in abstraction calls across a bounded scope (file, project, or namespace).

When should I use Migrate Static To Wrapper?

Migrate Static To Wrapper fits situations like: : replace DateTime.UtcNow with TimeProvider; replace DateTime.Now with TimeProvider; migrate static calls to wrapper; bulk replace File.

How do I install Migrate Static To Wrapper in Claude Code?

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

How do I install Migrate Static To Wrapper in Codex?

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

Can I use Migrate Static To Wrapper 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 migrate-static-to-wrapper -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/migrate-static-to-wrapper, .gemini/skills/migrate-static-to-wrapper, .github/skills/migrate-static-to-wrapper and .opencode/skills/migrate-static-to-wrapper in your project.

What does Migrate Static To Wrapper need to run?

Going by SKILL.md and its folder, Migrate Static To Wrapper needs the command-line tools its instructions call (dotnet).

Does Migrate Static To Wrapper 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 Migrate Static To Wrapper 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 Migrate Static To Wrapper use?

Migrate Static To Wrapper 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 Migrate Static To Wrapper use?

About 2.1k tokens (SKILL.md is roughly 8.3k 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 Migrate Static To Wrapper?

Skills that share tags, products or a category with Migrate Static To Wrapper: Migrate Core Code to Submodules (tinyhumansai/openhuman, 42k stars), Migrate Internal Package into Ghost (TryGhost/Ghost, 55k stars), Next Cache Components Adoption (vercel/next.js, 143k stars) and Deprecate R Functions and Arguments (tidyverse/dplyr, 5.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Migrate Static To Wrapper?

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 8, 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.