Testably.Abstractions.Migration 0.2.0

Prefix Reserved
dotnet add package Testably.Abstractions.Migration --version 0.2.0
                    
NuGet\Install-Package Testably.Abstractions.Migration -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Testably.Abstractions.Migration" Version="0.2.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Testably.Abstractions.Migration" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Testably.Abstractions.Migration">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Testably.Abstractions.Migration --version 0.2.0
                    
#r "nuget: Testably.Abstractions.Migration, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Testably.Abstractions.Migration@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Testably.Abstractions.Migration&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Testably.Abstractions.Migration&version=0.2.0
                    
Install as a Cake Tool

Testably.Abstractions.Migration

Changelog

Nuget Coverage

A Roslyn analyzer and code-fix provider that migrates System.IO.Abstractions (TestableIO) usage of MockFileSystem and MockFileData to the Testably.Abstractions MockFileSystem API. Drop the package into a project that uses System.IO.Abstractions.TestingHelpers and the analyzer flags each construct it can migrate; the accompanying code fix rewrites the call site.

Installation

The migration package is a one-shot development tool — install it, migrate, then uninstall. It ships only the analyzer and code fixer, not runtime code, and is marked as a DevelopmentDependency so it never flows transitively to consumers of your test project.

Because the package does not pull Testably.Abstractions.Testing transitively, you must reference it yourself in the project being migrated. Otherwise the rewritten call sites would compile while the migration package is installed but stop compiling the moment you remove it.

dotnet add package Testably.Abstractions.Testing
dotnet add package Testably.Abstractions.Migration
  1. Reference the target library. Add Testably.Abstractions.Testing to the project you want to migrate (see above). Existing System.IO.Abstractions.TestingHelpers usage keeps compiling side-by-side.
  2. Install the migration package. Adds the analyzer. Every supported construct is reported as warning TestablyM001.
  3. Apply the code fix. Use your IDE (Visual Studio, Rider, VS Code with C# Dev Kit) to fix diagnostics one by one, or run dotnet format analyzers to apply every available fix in bulk.
  4. Address manual-review diagnostics. Some patterns have no safe automatic rewrite (see Manual review). The analyzer reports them so they are discoverable; you migrate each call site by hand.
  5. Remove System.IO.Abstractions.TestingHelpers. Once the analyzer is quiet, drop the dependency.
  6. Uninstall the migration package. It has served its purpose and only adds analyzer overhead from here on.
dotnet remove package System.IO.Abstractions.TestingHelpers
dotnet remove package Testably.Abstractions.Migration

How it works

The analyzer emits a single diagnostic id, TestablyM001. Each call site carries a pattern property in Diagnostic.Properties that tells the code-fix provider which rewrite to perform. Patterns without an automatic rewrite still get a TestablyM001 warning so you can locate them — the code fix just declines to register an action.

Diagnostic Source library Code fix title
TestablyM001 System.IO.Abstractions Migrate System.IO.Abstractions MockFileSystem to Testably

Supported migrations

MockFileSystem constructors

TestableIO Testably
new MockFileSystem() new MockFileSystem()
new MockFileSystem(IDictionary<string, MockFileData>) new MockFileSystem() followed by per-entry Initialize… calls
new MockFileSystem(MockFileSystemOptions) new MockFileSystem(o => o…) with mapped option setters
new MockFileSystem(IDictionary<…>, MockFileSystemOptions) combined dict expansion + options lambda

IMockFileDataAccessor methods on MockFileSystem

TestableIO Testably
fs.AddFile(path, mockFileData) fs.Initialize().With…(…) (chain mapped from contents)
fs.AddEmptyFile(path) fs.File.Create(path).Dispose()
fs.AddDirectory(path) fs.Directory.CreateDirectory(path)
fs.RemoveFile(path) fs.File.Delete(path)
fs.MoveDirectory(source, dest) fs.Directory.Move(source, dest)
fs.FileExists(path) fs.File.Exists(path)
fs.AddDrive(name, mockDriveData) fs.WithDrive(name, d => d.Set…(…)) (mapped setters)
fs.AddFilesFromEmbeddedNamespace(path, assembly, prefix) fs.InitializeEmbeddedResourcesFromAssembly(path, assembly, relativePath: …) (when the assembly arg resolves statically and the prefix starts with the assembly name)

MockFileData property access

Reads of MockFileData properties (e.g. fs.GetFile(path).LastWriteTime) are routed to the matching Testably file-system call (e.g. fs.File.GetLastWriteTime(path)). Writes (e.g. fs.GetFile(path).LastWriteTime = value) become fs.File.SetLastWriteTime(path, value). The fixer only handles the one-shot fs.GetFile(path).Prop shape; property access through a captured reference is left for manual review (see below).

Manual review

These call sites are flagged with TestablyM001 but have no automatic rewrite, either because Testably.Abstractions has no equivalent surface or because a safe rewrite would require flow analysis the analyzer does not perform. Address each one by hand.

Pattern Why manual
MockFileData.AccessControl Windows FileSecurity has no Testably equivalent.
MockFileData.AllowedFileShare File-share locking has no Testably equivalent.
MockFileData.UnixMode Unix file permissions have no Testably equivalent.
new MockFileVersionInfo(...) File-version metadata has no Testably equivalent.
Subclassing MockFileSystem / MockFileData Inheritance contract differs in Testably.
new MockFileData(MockFileData template) Copy-clone semantics differ; no Testably equivalent.
Captured-reference MockFileData property access var data = fs.GetFile(path); data.Prop = … cannot be rewritten without local flow analysis.
fs.AllPaths / AllFiles / AllDirectories / AllDrives Testably has no enumeration properties; the natural replacements need a root or drive scope the analyzer cannot infer.
fs.MockTime(Func<DateTime>) TestableIO calls the delegate per timestamp request; Testably installs a fixed-then-mutable MockTimeSystem at construction. No observably-equivalent automatic rewrite for arbitrary delegates.
fs.AddFileFromEmbeddedResource(...) Testably exposes only a bulk InitializeEmbeddedResourcesFromAssembly with path-style matching; the single-file mapping is not safe to automate.

Suppressing the diagnostic

If you choose not to migrate a particular call site, suppress TestablyM001 per usage with the standard mechanisms:

#pragma warning disable TestablyM001
var fs = new MockFileSystem();
#pragma warning restore TestablyM001

or via an .editorconfig entry scoped to the file/folder:

[**/Legacy/**.cs]
dotnet_diagnostic.TestablyM001.severity = none
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 36 5/16/2026
0.1.0 51 5/15/2026